請教各位先進,為什麼執行邊緣化的結果只有處理約1/3的畫面? |
答題得分者是:nickcai2002
|
g9712714
一般會員 發表:9 回覆:6 積分:3 註冊:2009-12-29 發送簡訊給我 |
板大及各位先進大家好
小弟剛投入影像處理這個領域沒有很久 程式功力很弱(但我會盡力學) 有些問題想請各位幫我解惑一下,謝謝 以下程式碼是我從CCD擷取影像進來做二值化、侵蝕及邊緣化處理 而邊緣化是我參考某本書上寫的(/****/範圍裡) 可是出現的結果如圖一樣,只有在左邊的1/3範圍有做邊緣化的處理 我試了很久,還是沒辦法解決這個問題 所以想請各位幫我看一下是哪裡出了錯?? 謝謝! 問題問的太簡單或不得體還請各位包涵!!謝謝 [code cpp] void __fastcall TForm1::Timer1Timer(TObject *Sender) { //----抓取bmp檔並存為1.bmp----------- Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap(); EzCapCamera1->CapBitmapFrame(Bitmap1); EzCapCamera1->CapBmpPic("1.bmp"); Image1->Picture->LoadFromFile("1.bmp"); //---- 抓取ScrollBar的position設為Threshold,並以此值做二值化 Bitmap1->PixelFormat=pf24bit; Bitmap1->Assign(Image1->Picture); int Threshold; Threshold = (int)ScrollBar1->Position; Edit1->Text=ScrollBar1->Position; Byte *ptr; Byte gray; for (int y=0; y { ptr=(Byte *)Bitmap1->ScanLine[y]; for(int x=0;x { 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; } } } //------侵蝕--------------------- Byte *sptr; for(int i=0;i { sptr=(Byte*)Bitmap1->ScanLine[i]; for (int j=0;j { p1[j][i]=sptr[j*3]; } } for (int i=0;i { sptr=(Byte*)Bitmap1->ScanLine[i]; for (int j=0;j { sptr[j*3]=ErosionFilter(j,i); sptr[j*3 1]=ErosionFilter(j,i); sptr[j*3 2]=ErosionFilter(j,i); } } /****************************************************************/ /****************************************************************/ Byte *ctr, *tctr, *uptr, *dptr; int up, down, left, right, sum1; Graphics::TBitmap *TheBitmap,*TempBitmap; //----讓指標TheBitmap指向擬執行邊緣檢測之影像 //// TheBitmap=Image1->Picture->Bitmap; 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 { 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; } // end x }// end y // delete TheBitmap; /****************************************************************/ /****************************************************************/ Form1->Image1->Picture->Assign(TheBitmap); [/code] |
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
|
g9712714
一般會員 發表:9 回覆:6 積分:3 註冊:2009-12-29 發送簡訊給我 |
|
nickcai2002
一般會員 發表:3 回覆:20 積分:24 註冊:2004-11-18 發送簡訊給我 |
|
g9712714
一般會員 發表:9 回覆:6 積分:3 註冊:2009-12-29 發送簡訊給我 |
非常感謝nickcai2002 前輩的回答
已經順利使整張都能做邊緣化處理 但是處理的畫面很奇怪 他好像沒有針對目前的畫面做處理(感覺像是放大 斜拍) 如圖 上面那張是我對著目標物 可是卻沒有處理的東西 下面那張我把鏡頭水平右移後才有東西處理 我有試著去改變處理畫面的大小 可是都沒有成效 希望前輩可以在指點我一下問題出在哪裡? 十分感謝! [code cpp] #include #include <math.h><br />#pragma hdrstop #include "Unit1.h" #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "EzCapCamera" #pragma resource "*.dfm" TForm1 *Form1; int p1[360][240]; int HeightData_TABLE[76] = {58800,52000,45900,40700,36300,32600,29400,26800,24800,23100,20900,19100,18000,17000,15900,14700,13500,12500,11800,11200,10700,10200,9710,9160,8480,7870,7540,7250,6900,6550,6200,5860,5470,5130,4880,4700,4600,4520,4460,4390,4300,4160,3990,3810,3610,3440,3260,3080,2900,2750,2630,2550,2480,2420,2360,2310,2260,2220,2180,2140,2090,2030,1950,1860,1780,1710,1650,1590,1540,1490,1450,1410,1380,1350,1340,1330}; FILE *fp; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //-------------------------------------------- int __fastcall TForm1::ErosionFilter(int i,int j) { int Erosion; int p[10]; p[1]=p1[i-1][j-1]; p[2]=p1[i][j-1]; p[3]=p1[i 1][j-1]; p[4]=p1[i-1][j]; p[5]=p1[i][j]; p[6]=p1[i 1][j]; p[7]=p1[i-1][j 1]; p[8]=p1[i][j 1]; p[9]=p1[i 1][j 1]; Erosion=(p[1]&p[2]&p[3]&p[4]&p[5]&p[6]&p[7]&p[8]&p[9]); if (Erosion<0) Erosion=(-1)*Erosion; return (Erosion); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { EzCapCamera1->CameraDisplay(); //開啟攝影機攝影機畫面 } //--------------------------------------------------------------------------- void __fastcall TForm1::Button2Click(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button3Click(TObject *Sender) { EzCapCamera1->CameraClose(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button4Click(TObject *Sender) { Timer1->Enabled=false; } //--------------------------------------------------------------------------- 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; y { ptr=(Byte *)Bitmap1->ScanLine[y]; for(int x=0;x { 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); } //--------------------------------------------------------------------------- void __fastcall TForm1::Button7Click(TObject *Sender) { Timer1->Enabled=true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject *Sender) { //----抓取bmp檔並存為1.bmp----------- Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap(); EzCapCamera1->CapBitmapFrame(Bitmap1); EzCapCamera1->CapBmpPic("1.bmp"); Image1->Picture->LoadFromFile("1.bmp"); //---- 抓取ScrollBar的position設為Threshold,並以此值做二值化 //Bitmap1->PixelFormat=pf24bit; //Bitmap1->Assign(Image1->Picture); Bitmap1->Assign(Image1->Picture); Bitmap1->PixelFormat=pf24bit; int Threshold; Threshold = (int)ScrollBar1->Position; Edit1->Text=ScrollBar1->Position; Byte *ptr; Byte gray; for (int y=0; y { ptr=(Byte *)Bitmap1->ScanLine[y]; for(int x=0;x { 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; } } } /****************************************************************/ /****************************************************************/ Byte *ctr, *tctr, *uptr, *dptr; int up, down, left, right, sum1; Graphics::TBitmap *TheBitmap,*TempBitmap; //----讓指標TheBitmap指向擬執行邊緣檢測之影像 //// TheBitmap=Image1->Picture->Bitmap; TheBitmap=Bitmap1; //------------產生一臨時圖像以便作邊緣檢測--------------- TempBitmap= new Graphics::TBitmap(); TempBitmap->Assign(TheBitmap); //-------------------執行邊緣檢測----------------------------------- for (int y=0; y < Bitmap1->Height; y ) { up=y-1; down=y 1; if (up<0) up=Bitmap1->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 < Bitmap1->Width; x ) { left=x-1; right=x 1; if (left<0) left=Bitmap1->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*3]=ctr[x*3 1]=ctr[x*3 2]=(Byte)sum1; } // end x }// end y delete TempBitmap; /****************************************************************/ /****************************************************************/ //Repaint(); //Graphics->Assign(Bitmap1); Form1->Image1->Picture->Assign(Bitmap1); //------計算面積以及重心--------- Byte *tptr; int r,g,b; int k,l; float XX,YY; float Xp,Yp,Sq,dist,d; int sum=1, X=0, Y=0; int x,h=0; Bitmap1->Assign(Image1->Picture->Bitmap); Bitmap1->PixelFormat=pf24bit; for (int k=0;k { tptr=(Byte*)Bitmap1->ScanLine[k]; for (int l=0;l { b=tptr[l*3]; g=tptr[l*3 1]; r=tptr[l*3 2]; if(r==255&&g==255&&b==255&&k { sum=sum 1; X=X l; Y=Y k; } } } XX=(float)X/(float)sum; YY=(float)Y/(float)sum; //-----求出畫面上水平位移dist------- Xp=XX-319; Yp=YY-239; Sq=pow(Xp,2) pow(Yp,2); dist=sqrt(Sq); sum=sum-1; //---高度換算------ for (x=0;x<=74;x ) { if(HeightData_TABLE[x] > sum && sum >= HeightData_TABLE[x 1]) { h=(x 15)*10; d=dist/400*h; IntToStr(h); Form1->Edit5->Text=h; } if (sum<1330) { Form1->Edit5->Text="over 900"; } } FloatToStr(d); Form1->Edit6->Text=d; FloatToStr(sum); Form1->Edit2->Text=sum; FloatToStr(XX); FloatToStr(YY); Form1->Edit3->Text=XX; Form1->Edit4->Text=YY; delete Bitmap1; } [/code] |
nickcai2002
一般會員 發表:3 回覆:20 積分:24 註冊:2004-11-18 發送簡訊給我 |
|
g9712714
一般會員 發表:9 回覆:6 積分:3 註冊:2009-12-29 發送簡訊給我 |
非常感謝nickcai2002 前輩的回答:
閥值我有調過,且應該不是閥值的問題(圖片清楚與否) 我剛剛發現我的圖片掛掉了 十分的抱歉!(鞠恭) 在此補上圖片 上面那張是我對著目標物 可是卻沒有處理的東西 下面那張我把鏡頭水平往右移一些後才有出現目標進行處理 ===================引 用 nickcai2002 文 章=================== 你現在的疑問應該是調整"閥值"到適合的值時會有你要的結果, |
istillloving
高階會員 發表:33 回覆:182 積分:183 註冊:2008-10-09 發送簡訊給我 |
我不知道 Graphics::TBitmap *bmp = new Graphics::TBitmap(); 這是不是三維的陣列 還是有使用到Struct
但是把你的 x =3 改成 x 看看吧 [code cpp] for (int y=0; y { ptr=(Byte *)Bitmap1->ScanLine[y]; for(int x=0;x { } } [/code]
------
恩...
編輯記錄
istillloving 重新編輯於 2010-01-08 15:12:22, 註解 無‧
|
g9712714
一般會員 發表:9 回覆:6 積分:3 註冊:2009-12-29 發送簡訊給我 |
非常感謝 istillloving 前輩的回答
我照前輩的話去試試看,結果還是不行 不過您的話指點了我一個很大的方向 嘗試了許久 總算是有比較像樣的結果了 十分的感謝您!(當然也要改謝其他願意撥空回答我問題的前輩) 以下是我做修改的部分 [code cpp] for (int x=0; x for (int x=0; x [/code] 以及 [code cpp] ctr[x*3]=ctr[x*3 1]=ctr[x*3 2]=(Byte)sum1;//改成下面 ctr[x]=ctr[x 1]=ctr[x 2]=(Byte)sum1; [/code] 附圖 ------------------------------------------------------------------------------- 感謝有您們熱心的指導,才使得晚輩會更加努力去學習!! ===================引 用 istillloving 文 章=================== 我不知道 Graphics::TBitmap *bmp = new Graphics::TBitmap(); 這是不是三維的陣列 還是有使用到Struct 但是把你的 x =3 改成 x 看看吧 [code cpp] for (int y=0; y { } } [/code] |
istillloving
高階會員 發表:33 回覆:182 積分:183 註冊:2008-10-09 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |