關於size filter的影像處理 |
尚未結案
|
enfin
一般會員 發表:5 回覆:4 積分:1 註冊:2005-07-11 發送簡訊給我 |
我用ccd擷取畫面然後先做灰階再來二值化,這些都沒問題,只是要用size filter濾掉濾不掉,但是我後來二值化後先用存檔的動作,做size filter前在用開檔的動作就比較沒問題ㄌ,請問有辦法不用存檔開檔的動作就可以完成嗎?還有灰階+二值化後我加了pBitmap2->PixelFormat = pf8bit;後才變成8 bit,有辦法改什麼程式就可以直接是24bit變成8bitㄌ嗎?附程式如下,這是寫在Timer底下的:
Graphics::TBitmap *pBitmap1= new Graphics::TBitmap(); pBitmap1->Assign(Form1->Image1->Picture); BYTE *ptr1; for(int y=0;y<240;y ) { ptr1=(BYTE*)pBitmap1->ScanLine[239-y]; for(int x=0;x<320;x ) { ptr1[x*3]=B[y][x]; ptr1[x*3 1]=G[y][x]; ptr1[x*3 2]=R[y][x]; } } Image1->Canvas->Draw(0,0,pBitmap1); delete pBitmap1; //灰階 二值化----------------------------------------- Graphics::TBitmap *pBitmap2 = new Graphics::TBitmap(); Byte *ptr2; int r,g,b; int gray; int i,j; pBitmap2->Assign(Image1->Picture); for(j=0;jHeight;j ) { ptr2 = (Byte *)pBitmap2->ScanLine[j]; for(i=0;iWidth;i ) { b=ptr2[i*3]; g=ptr2[i*3 1]; r=ptr2[i*3 2]; gray=0.299*r 0.587*g 0.114*b; if (gray>90) gray=255; else gray=0; ptr2[i*3]=(Byte)gray; ptr2[i*3 1]=(Byte)gray; ptr2[i*3 2]=(Byte)gray; } } pBitmap2->PixelFormat = pf8bit;//這行有辦法換成較好的程式嗎? pBitmap2->SaveToFile("F:\\8it.bmp");//這裡需要先存檔? Image1->Canvas->Draw(0,0,pBitmap2); delete pBitmap2; //size filter----------------------------------------- Image2->Picture->Assign(Image1->Picture); Graphics::TBitmap *pBitmap3 = new Graphics::TBitmap(); Byte *ptr3; unsigned int im[240][320],mask[240][320],label[2000]; int index=1; int max=0,imax=0; pBitmap3->LoadFromFile("F:\\8it.bmp");//這裡要叫黨出來,才能做size filter for (int m=0;m<240;m ) //初始 { for (int n=0;n<320;n ) { im[m][n]=0; mask[m][n]=0; } } for (int y = 0; y < pBitmap3->Height; y ) { ptr3 = (BYTE*)pBitmap3->ScanLine[y]; for (int x = 0; x < pBitmap3->Width; x ) im[y][x]=*(ptr3 x); //將圖讀入im[y][x]矩陣 } //前期編號 for(int i=0;i<240;i ) //Height 2 { for(int j=0;j<320;j ) //Width 2 { if(im[i][j]==0) //3(a) mask[i][j]=index; if(im[i][j]==0 && mask[i][j-1]!=0) //3(b) mask[i][j]=mask[i][j-1]; if(im[i][j]==255 && mask[i][j-1]!=0) //3(c) index=index 1; } index=index 1; } //後期編號 for(int i=0;i<240;i ) //Height 1 { for(int j=0;j<320;j ) //Width 1 { if(mask[i][j]!=0) //2(a) { if(mask[i-1][j]!=0 && mask[i][j-1]==0) //2(a)上點 mask[i][j]=mask[i-1][j]; else if(mask[i-1][j]==0 && mask[i][j-1]!=0) //2(a)左點 mask[i][j]=mask[i][j-1]; else if(mask[i-1][j]!=0 && mask[i][j-1]!=0 && mask[i-1][j]==mask[i][j-1] ) //2(b) mask[i][j]=mask[i][j-1]; else if(mask[i-1][j]!=0 && mask[i][j-1]!=0 && mask[i-1][j]!=mask[i][j-1] ) { //2(c) mask[i][j]=mask[i][j-1]; //複製左方編號 int p=mask[i][j-1]; //左方編號 int q=mask[i-1][j]; //上方編號 for(int m=0;m<240;m ) //掃描全圖 { for(int n=0;n<320;n ) { if(mask[m][n]==q) mask[m][n]=p; } } } } } } //SizeFilter部分(計數) for (int i=0;i<2000;i ) //初始 label[i]=0; for (int m=0;m<240;m ) //計數開始 for (int n=0;n<320;n ) if (mask[m][n]!=0) label[mask[m][n]]=label[mask[m][n]] 1; for(int i=0;i<2000;i ) // 找最多的數值 { if(label[i]>max) { max=label[i]; imax=i; } } Label1->Caption=IntToStr(imax); //顯示最多個數的數值 //保留最多數字的部份 for(int y=0;y<240;y ) { for(int x=0;x<320;x ) { if(mask[y][x]!=imax) im[y][x]=255; } } //填回原來的圖形 for (int y = 0; y < pBitmap3->Height; y ) //im矩陣填入*ptr { ptr3 = (BYTE*)pBitmap3->ScanLine[y]; for (int x = 0; x < pBitmap3->Width; x ) *(ptr3 x)=(Byte)im[y][x]; } Image2->Canvas->Draw(0,0,pBitmap3); delete pBitmap3;感謝各位高手! |
arisaka_matsuri
高階會員 發表:25 回覆:205 積分:231 註冊:2003-10-19 發送簡訊給我 |
大概看了一下你的程式,僅設定PixelFormat屬性把24bit轉為8bit影像,有時候會得到意外的效果。特別是8bit影像需要調色盤才能正確顯示顏色,沒有指定調色盤有時候會造成顏色錯誤的情形。調色盤的設定,站內有文章。 由於你的size filter作用對象是im[][],所以將你的程式改寫,請你參考一下~
Graphics::TBitmap *pBitmap1= new Graphics::TBitmap(); // // ...保留未動... // // delete pBitmap1; ← pBitmap1還要用 unsigned int im[240][320], mask[240][320], label[2000]; //灰階 二值化----------------------------------------- Graphics::TBitmap *pBitmap2 = new Graphics::TBitmap(); pBitmap2->PixelFormat = pf8bit; pBitmap2->Palette = ???? // 如果要顯示,最好給定調色盤 pBitmap2->Width = Image1->Picture->Bitmap->Width; pBitmap2->Height = Image1->Picture->Bitmap->Height; Byte *ptr2; int gray; int i,j; for(int y = 0; y < pBitmap2->Height; y ) { ptr1 = (Byte *)pBitmap1->ScanLine[y]; ptr2 = (Byte *)pBitmap2->ScanLine[y]; for(int x = 0; x < pBitmap2->Width; x ) { gray = 0.299*ptr1[i*3 2] 0.587*ptr1[i*3 1] 0.114*ptr1[i*3]; if(gray > 90) gray = 255; else gray = 0; ptr2[x] = gray; // 為了要顯示,把值填進 pBitmap2 im[y][x] = gray; // 為了做之後的計算 mask[y][x] = 0; // 順便初始化 } } Image1->Canvas->Draw(0,0,pBitmap2); delete pBitmap1; ptr1 = NULL; delete pBitmap2; ptr2 = NULL; //size filter----------------------------------------- Image2->Picture->Assign(Image1->Picture); Graphics::TBitmap *pBitmap3 = new Graphics::TBitmap(); pBitmap3->PixelFormat = pf8bit; pBitmap3->Palette = ???? // 如果要顯示,最好給定調色盤 pBitmap3->Width = Image2->Picture->Bitmap->Width; // 看來只要是 320 就對了 pBitmap3->Height = Image2->Picture->Bitmap->Height; // 看來只要是 240 就可以 Byte *ptr3; int index=1; int max=0,imax=0; //前期編號 for(int i=0;i<240;i ) //Height 2 // // ...保留未動... // } //填回原來的圖形 for (int y = 0; y < pBitmap3->Height; y ) //im矩陣填入*ptr { ptr3 = (BYTE*)pBitmap3->ScanLine[y]; for (int x = 0; x < pBitmap3->Width; x ) *(ptr3 x)=(Byte)im[y][x]; } Image2->Canvas->Draw(0,0,pBitmap3); delete pBitmap3;修改過的程式仍有點小亂,還可以更簡化。建議能把部分功能(像是size filter)寫成函式,好閱讀也好維護。 我沒有實際執行過,所以請視情形再自行修改吧~ |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |