線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2465
推到 Plurk!
推到 Facebook!

請教各位先進,為什麼執行邊緣化的結果只有處理約1/3的畫面?

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


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

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-12-31 02:11:55 IP:218.163.xxx.xxx 訂閱
板大及各位先進大家好
小弟剛投入影像處理這個領域沒有很久
程式功力很弱(但我會盡力學)
有些問題想請各位幫我解惑一下,謝謝
以下程式碼是我從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; 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;
}

}
}

//------侵蝕---------------------
Byte *sptr;
for(int i=0;iHeight;i )
{
sptr=(Byte*)Bitmap1->ScanLine[i];
for (int j=0;jWidth;j )
{
p1[j][i]=sptr[j*3];
}
}
for (int i=0;iHeight;i )
{
sptr=(Byte*)Bitmap1->ScanLine[i];
for (int j=0;jWidth;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 Width; 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]


附加檔案:4b3b97eb54ed1_test.gif
編輯記錄
g9712714 重新編輯於 2009-12-31 02:18:49, 註解 無‧
g9712714 重新編輯於 2010-01-05 21:55:55, 註解 無‧
g9712714 重新編輯於 2010-01-06 17:24:09, 註解 無‧
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-12-31 09:52:47 IP:122.116.xxx.xxx 訂閱
試試順序交換一下

  • g9712714
    一般會員


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

    發送簡訊給我
    #3 引用回覆 回覆 發表時間:2009-12-31 16:55:26 IP:140.125.xxx.xxx 訂閱
    感謝副站長的回覆
    我照你的方法去改,結果還是一樣耶
    我在猜想是不是在作邊緣檢測那邊的讀圖有問題呢?
    謝謝!

    ===================引 用 taishyang 文 章===================
    試試順序交換一下
      Bitmap1->Assign(Image1->Picture);
    1. Bitmap1->PixelFormat=pf24bit;
    nickcai2002
    一般會員


    發表:3
    回覆:20
    積分:24
    註冊:2004-11-18

    發送簡訊給我
    #4 引用回覆 回覆 發表時間:2010-01-05 09:57:01 IP:122.201.xxx.xxx 未訂閱
    1. for (int x=0; x Width; x )
    2. {
    3. left=x-1;
    4. right=x 1;
    5. if (left<0) left=TheBitmap->Width -1;
    6. if (right==TheBitmap->Width) right=0;
    7. sum1= (int)(-uptr[left]- uptr[x]-uptr[right]
    8. -tctr[left] 8*tctr[x]-tctr[right]
    9. -dptr[left]- dptr[x]-dptr[right]);
    10. //----------邊緣檢測結果可能大於255或小於0----------------------
    11. //----------若大於255則設為255----------------------------------
    12. //----------若小於0則設為0--------------------------------------
    13. if(sum1<0) sum1 =0;
    14. if(sum1>255) sum1=255;
    15. // ctr[x]=(Byte)sum1;
      • ctr[x*3]=ctr[x*3 1]=ctr[x*3 2]=(Byte)sum1; //<------ 改成這樣試看看
    16. } // end x
    g9712714
    一般會員


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

    發送簡訊給我
    #5 引用回覆 回覆 發表時間:2010-01-05 22:15:56 IP:140.125.xxx.xxx 訂閱
    非常感謝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; 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);

    }
    //---------------------------------------------------------------------------


    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; 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;
    }

    }
    }


    /****************************************************************/
    /****************************************************************/

    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;kHeight;k )
    {
    tptr=(Byte*)Bitmap1->ScanLine[k];
    for (int l=0;lWidth;l )
    {
    b=tptr[l*3];
    g=tptr[l*3 1];
    r=tptr[l*3 2];
    if(r==255&&g==255&&b==255&&kHeight&&lWidth)
    {
    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]




    編輯記錄
    g9712714 重新編輯於 2010-01-05 22:25:59, 註解 無‧
    g9712714 重新編輯於 2010-01-06 17:54:51, 註解 無‧
    g9712714 重新編輯於 2010-01-06 18:08:02, 註解 無‧
    nickcai2002
    一般會員


    發表:3
    回覆:20
    積分:24
    註冊:2004-11-18

    發送簡訊給我
    #6 引用回覆 回覆 發表時間:2010-01-06 16:14:27 IP:122.201.xxx.xxx 未訂閱
    你現在的疑問應該是調整"閥值"到適合的值時會有你要的結果,

    g9712714
    一般會員


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

    發送簡訊給我
    #7 引用回覆 回覆 發表時間:2010-01-06 18:17:47 IP:218.163.xxx.xxx 訂閱
    非常感謝nickcai2002 前輩的回答:
    閥值我有調過,且應該不是閥值的問題(圖片清楚與否)
    我剛剛發現我的圖片掛掉了
    十分的抱歉!(鞠恭)
    在此補上圖片

    上面那張是我對著目標物 可是卻沒有處理的東西
    下面那張我把鏡頭水平往右移一些後才有出現目標進行處理




    ===================引 用 nickcai2002 文 章===================
    你現在的疑問應該是調整"閥值"到適合的值時會有你要的結果,

    istillloving
    高階會員


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

    發送簡訊給我
    #8 引用回覆 回覆 發表時間:2010-01-08 15:11:19 IP:61.223.xxx.xxx 訂閱
    我不知道 Graphics::TBitmap *bmp = new Graphics::TBitmap(); 這是不是三維的陣列 還是有使用到Struct



    但是把你的 x =3 改成 x 看看吧


    [code cpp]
    for (int y=0; yHeight;y )
    {
    ptr=(Byte *)Bitmap1->ScanLine[y];
    for(int x=0;xWidth*3;x =3)

    {
    }
    }
    [/code]


    ------
    恩...
    編輯記錄
    istillloving 重新編輯於 2010-01-08 15:12:22, 註解 無‧
    g9712714
    一般會員


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

    發送簡訊給我
    #9 引用回覆 回覆 發表時間:2010-01-12 23:59:40 IP:140.125.xxx.xxx 訂閱
    非常感謝 istillloving 前輩的回答
    我照前輩的話去試試看,結果還是不行
    不過您的話指點了我一個很大的方向
    嘗試了許久
    總算是有比較像樣的結果了
    十分的感謝您!(當然也要改謝其他願意撥空回答我問題的前輩)
    以下是我做修改的部分
    [code cpp]
    for (int x=0; x Width*3; x =3);///改成下面
    for (int x=0; x Width*3; x =3);
    [/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

    發送簡訊給我
    #10 引用回覆 回覆 發表時間:2010-01-13 10:10:40 IP:140.127.xxx.xxx 訂閱
    這應該是旗標沒指對而已啦

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