全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1573
推到 Plurk!
推到 Facebook!

邊緣化後物體右邊的線條斷斷續續的,請問前輩們可能會是什麼問題呢?

答題得分者是:istillloving
g9712714
一般會員


發表:9
回覆:6
積分:3
註冊:2009-12-29

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-01-13 00:20:35 IP:140.125.xxx.xxx 訂閱
首先要感謝熱情的前輩們願意撥空指點我上一題的問題[問題] 請教各位先進,為什麼執行邊緣化的結果只有處理約1/3的畫面?
我現在這個問題也是從上面延伸下來的
<meta content="Word.Document" name="ProgId" /><meta content="Microsoft Word 11" name="Generator" /><meta content="Microsoft Word 11" name="Originator" /><link href="file:///C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\msohtml1\01\clip_filelist.xml" rel="File-List" /><style type="text/css"><br /><!--
/* Font Definitions */
@font-face
{font-family:新細明體;
panose-1:2 2 3 0 0 0 0 0 0 0;
mso-font-alt:PMingLiU;
mso-font-charset:136;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:3 137232384 22 0 1048577 0;}
@font-face
{font-family:"\@新細明體";
panose-1:2 2 3 0 0 0 0 0 0 0;
mso-font-charset:136;
mso-generic-font-family:roman;
mso-font-pitch:variable;
mso-font-signature:3 137232384 22 0 1048577 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:新細明體;
mso-font-kerning:1.0pt;}
/* Page Definitions */
@page
{mso-page-border-surround-header:no;
mso-page-border-surround-footer:no;}
@page Section1
{size:612.0pt 792.0pt;
margin:72.0pt 90.0pt 72.0pt 90.0pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style><span ="font-size: 12pt; font-family: 'Times New Roman'">

如圖中紅色圈起部分為什麼我圖形中的右邊其邊緣化的線條不是很明顯?(斷斷續續的)如圖中黃色圈起部分為什麼當有物體經過畫面左邊三分之一的時候會多出這條線,這條線的位置在畫面的左邊三分之一
不知道是不是我邊緣化的程式寫的不夠完整呢?
謝謝!



[code cpp]

Byte *ctr, *tctr, *uptr, *dptr;
int up, down, left, right, sum1;
Graphics::TBitmap *TheBitmap,*TempBitmap;
//----讓指標TheBitmap指向擬執行邊緣檢測之影像
Bitmap1->PixelFormat=pf24bit;
TheBitmap=Bitmap1;
//------------產生一臨時圖像以便作邊緣檢測---------------
TempBitmap= new Graphics::TBitmap();
TempBitmap->Assign(TheBitmap);
//-------------------執行邊緣檢測-----------------------------------
for (int y=0; y < TheBitmap->Height; y )
{
up=y-1;
down=y 1;
if (up<0) up=TheBitmap->Height -1;
if (down==TheBitmap->Height) down=0;
ctr = (Byte*)TheBitmap->ScanLine[y];
tctr = (Byte*)TempBitmap->ScanLine[y];
uptr = (Byte*)TempBitmap->ScanLine[up];
dptr = (Byte*)TempBitmap->ScanLine[down];
for (int x=0; x Width*3; x =3)
{
left=x-1;
right=x 1;
if (left<0) left=TheBitmap->Width -1;
if (right==TheBitmap->Width) right=0;
sum1= (int)(-uptr[left]- uptr[x]-uptr[right]
-tctr[left] 8*tctr[x]-tctr[right]
-dptr[left]- dptr[x]-dptr[right]);
//----------邊緣檢測結果可能大於255或小於0----------------------
//----------若大於255則設為255----------------------------------
//----------若小於0則設為0--------------------------------------
if(sum1<0) sum1 =0;
if(sum1>255) sum1=255;
// ctr[x]=(Byte)sum1;
ctr[x]=ctr[x 1]=ctr[x 2]=(Byte)sum1;
} // end x
}// end y
delete TempBitmap;

Form1->Image1->Picture->Assign(Bitmap1);

[/code]






-------------------------------------------------------------------------------
感謝有您們熱心的指導,才使得晚輩會更加努力去學習!!
編輯記錄
g9712714 重新編輯於 2010-01-13 15:32:34, 註解 無‧
g9712714 重新編輯於 2010-01-13 15:32:34, 註解 無‧
istillloving
高階會員


發表:33
回覆:182
積分:183
註冊:2008-10-09

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-01-13 10:18:15 IP:140.127.xxx.xxx 訂閱
其實我看不太懂你的做法

但是邊界的設定


[code cpp]
if (up<0) up=TheBitmap->Height -1;

if (down==TheBitmap->Height) down=0;

[/code]


是不是要改成這樣才對阿



[code cpp]
if(up<0)
{
up=0;
}
if(down==TheBitmap->Height)
{
down=TheBitmap->Height -1;
}

[/code]

我覺得你好像寫反了
另一個Left right判斷式也是


[code cpp]
for (int x=0; x Width*3; x =3)
ctr[x]=ctr[x 1]=ctr[x 2]=(Byte)sum1;

// 一般好像比較多人用下面的寫法
for (int x=0; x Width; x )
ctr[x*3]=ctr[x*3 1]=ctr[x*3 2]=(Byte)sum1;

[/code]


------
恩...
編輯記錄
istillloving 重新編輯於 2010-01-13 10:19:29, 註解 無‧
istillloving 重新編輯於 2010-01-13 10:24:25, 註解 無‧
istillloving 重新編輯於 2010-01-13 10:26:15, 註解 無‧
g9712714
一般會員


發表:9
回覆:6
積分:3
註冊:2009-12-29

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-01-13 15:46:49 IP:218.163.xxx.xxx 訂閱
istillloving前輩你好:
由於小弟是初學者
所以我是參考"C Builder與影像處理(黃文吉編著)"裡面的邊緣化下去做的
我照您的話改成你教我的邊界設定寫法
如圖一上
有成功解決左邊那條線的問題(黃色線為原本會出現的問題)
可是物體邊緣的線條還是斷斷續續的
反覆檢查程式還是看不出是哪裡的問題,讓我覺得很納悶(小弟不才)
還有請前輩們指點一二
十分感謝!


而以下兩行並沒有照您的話去改
[code cpp]
for (int x=0; x Width*3; x =3);
ctr[x]=ctr[x 1]=ctr[x 2]=(Byte)sum1;
[/code]
因為改了結果就像圖一下及圖二





圖一

************************************************************************************************************************************************


圖二


至於會這樣做的原因是上面程式有這樣寫到
所以我才會從這個方向去改

[code cpp]
void __fastcall TForm1::ScrollBar1Change(TObject *Sender)
{
Graphics::TBitmap *Bitmap1= new Graphics::TBitmap();
Bitmap1->PixelFormat=pf24bit;
Bitmap1->Assign(Image1->Picture);
int Threshold;
Threshold = (int)ScrollBar1->Position;
Byte *ptr;
Byte gray;
for (int y=0; yHeight;y )
{
ptr=(Byte *)Bitmap1->ScanLine[y];
for(int x=0;xWidth*3;x =3)
{
gray=(ptr[x] ptr[x 1] ptr[x 2])/3;

if(gray>Threshold)
{
ptr[x]=255;
ptr[x 1]=255;
ptr[x 2]=255;
}
else
{
ptr[x]=0;
ptr[x 1]=0;
ptr[x 2]=0;
}
}
}
Repaint();
Form1->Image1->Picture->Assign(Bitmap1);

}
[/code]



-------------------------------------------------------------------------------
感謝有您們熱心的指導,才使得晚輩會更加努力去學習!!










===================引 用 istillloving 文 章===================
其實我看不太懂你的做法

但是邊界的設定


[code cpp]
if (up<0) up=TheBitmap->Height -1;?

if (down==TheBitmap->Height) down=0;

[/code]


是不是要改成這樣才對阿



[code cpp]
if(up<0)
{
? up=0;
}
if(down==TheBitmap->Height)
{
? down=TheBitmap->Height -1;
}

[/code]

我覺得你好像寫反了
另一個Left right判斷式也是


[code cpp]
for (int x=0; x Width*3; x =3)?
ctr[x]=ctr[x 1]=ctr[x 2]=(Byte)sum1;
?
// 一般好像比較多人用下面的寫法
for (int x=0; x Width; x )?
ctr[x*3]=ctr[x*3 1]=ctr[x*3 2]=(Byte)sum1;

[/code]



istillloving
高階會員


發表:33
回覆:182
積分:183
註冊:2008-10-09

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-01-13 18:05:36 IP:140.127.xxx.xxx 訂閱
所以你現在完整的邊緣偵測的程式是哪一段?

一般最常用的找邊緣的方法就是套一個邊緣偵測的遮罩

而看你的公式


[code cpp]
sum1= (int)(-uptr[left]- uptr[x]-uptr[right]
-tctr[left] 8*tctr[x]-tctr[right]
-dptr[left]- dptr[x]-dptr[right]);

[/code]
這作法應該是罩上一個 3*3的遮罩

-1 -1 -1
-1 8 -1
-1 -1 -1

這個可能是他自己寫的
但是一般最常用的是 Sobel 3*3 遮罩

他的遮罩有分找水平邊緣和垂直邊緣

垂直 水平
-1 0 1 -1 -2 -1
-2 0 2 0 0 0
-1 0 1 1 2 1

做完Sobel之後 記得取絕對質

其實找出邊緣的概念很簡單 就是找出變化量

照出影像的梯度


假設一個3*3的原始影像係數如下

0 , 0 , 255
0 , 0 , 255
0 , 0 , 255

今天把找出垂直邊緣的Sobel罩上去的話會得到

(0*-1 0 255*1) ( 0*-2 0 255*2) (0*-1 0 255*1) = 1020

如果把找出水平邊緣的Sobel罩上去的話會得到

(0*-1 0*-2 255*-1) ( 0*0 0*0 255*0) (0*1 0*2 255*-1) = 0

就可以很容易的知道

這3*3的影像裡面有一個垂直邊緣存在

就很簡單的概念 找變化量 所以遮罩其實也可以自己設計

例如

0 -2 0
-2 4 -2
0 -2 0

這也是變化量的搜尋

試試看吧



------
恩...
編輯記錄
istillloving 重新編輯於 2010-01-13 18:26:19, 註解 無‧
istillloving 重新編輯於 2010-01-13 18:26:51, 註解 無‧
istillloving 重新編輯於 2010-01-13 21:11:24, 註解 無‧
g9712714
一般會員


發表:9
回覆:6
積分:3
註冊:2009-12-29

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-01-17 17:51:35 IP:140.125.xxx.xxx 訂閱
非常istillloving前輩的指導:
我仔細去思考你教我的方法及不斷的參考站上其他前輩的寫法
總算是把我的問題解決掉了
下圖是邊緣化 膨脹的結果



真的是感謝再感謝!!

----------------------------------------------
感謝有您們熱心的指導,才使得晚輩會更加努力去學習!!



===================引 用 istillloving 文 章===================
所以你現在完整的邊緣偵測的程式是哪一段?

一般最常用的找邊緣的方法就是套一個邊緣偵測的遮罩

而看你的公式


[code cpp]
sum1= (int)(-uptr[left]- uptr[x]-uptr[right]
-tctr[left] 8*tctr[x]-tctr[right]
-dptr[left]- dptr[x]-dptr[right]);

[/code]
這作法應該是罩上一個 3*3的遮罩

-1 -1 -1
-1 8 -1
-1 -1 -1

這個可能是他自己寫的
但是一般最常用的是 Sobel 3*3 遮罩

他的遮罩有分找水平邊緣和垂直邊緣

垂直 水平
-1 0 1 -1 -2 -1
-2 0 2 0 0 0
-1 0 1 1 2 1

做完Sobel之後 記得取絕對質

其實找出邊緣的概念很簡單 就是找出變化量

照出影像的梯度


假設一個3*3的原始影像係數如下

0 , 0 , 255
0 , 0 , 255
0 , 0 , 255

今天把找出垂直邊緣的Sobel罩上去的話會得到

(0*-1 0 255*1) ( 0*-2 0 255*2) (0*-1 0 255*1) = 1020

如果把找出水平邊緣的Sobel罩上去的話會得到

(0*-1 0*-2 255*-1) ( 0*0 0*0 255*0) (0*1 0*2 255*-1) = 0

就可以很容易的知道

這3*3的影像裡面有一個垂直邊緣存在

就很簡單的概念 找變化量 所以遮罩其實也可以自己設計

例如

0 -2 0
-2 4 -2
0 -2 0

這也是變化量的搜尋

試試看吧



系統時間:2024-04-26 15:05:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!