keikojason
初階會員
發表:37 回覆:63 積分:45 註冊:2004-05-10
發送簡訊給我
|
各位前輩好:
小弟有一個問題就是說要將一個圖二值化,不過二值化的點數是原圖的16分之一,也就是假設在一圖像中16點全都在範圍中就為一個白色點(255),若不足16點就一個黑色點(0),再將這些點顯示在另一張圖中(會比原圖變小),形成縮小的二值化圖~~在下面的部分是小弟用的二值化的方式~~不過不懂要怎樣去顯示另外縮小過後二值化圖~~如果對小弟上述不了解意思小弟畫一張圖示:
Graphics::TBitmap *Bmp = new Graphics::TBitmap();
Bmp->Assign(Image1->Picture->Bitmap);
for(j=0;jHeight;j++)
{
ptr = (Byte *)Bmp->ScanLine[j];
for(i=0;iWidth;i++)
{
b=ptr[i*3];
g=ptr[i*3+1];
r=ptr[i*3+2]; y = 0.299*r+0.587*g+0.114*b;
cr = 0.5*r-0.419*g-0.081*b+128;
cb = -0.169*r-0.332*g+0.5*b+128;
if(cr>75&&cr<110&&cb>85&&cb<133)
{ Bmp->Canvas->Pixels[j][i] == clWhite;
Bmp->Canvas->Pixels[j+1][i] == clWhite;
Bmp->Canvas->Pixels[j+2][i] == clWhite;
Bmp->Canvas->Pixels[j+3][i] == clWhite;
Bmp->Canvas->Pixels[j][i+1] == clWhite;
Bmp->Canvas->Pixels[j][i+2] == clWhite;
Bmp->Canvas->Pixels[j][i+3] == clWhite;
Bmp->Canvas->Pixels[j+1][i+1] == clWhite;
Bmp->Canvas->Pixels[j+1][i+2] == clWhite;
Bmp->Canvas->Pixels[j+1][i+3] == clWhite;
Bmp->Canvas->Pixels[j+2][i+1] == clWhite;
Bmp->Canvas->Pixels[j+2][i+2] == clWhite;
Bmp->Canvas->Pixels[j+2][i+3] == clWhite;
Bmp->Canvas->Pixels[j+3][i+1] == clWhite;
Bmp->Canvas->Pixels[j+3][i+2] == clWhite;
Bmp->Canvas->Pixels[j+3][i+3] == clWhite; }
else
{
Bmp->Canvas->Pixels[j][i] == clBlack;
Bmp->Canvas->Pixels[j+1][i] == clBlack;
Bmp->Canvas->Pixels[j+2][i] == clBlack;
Bmp->Canvas->Pixels[j+3][i] == clBlack;
Bmp->Canvas->Pixels[j][i+1] == clBlack;
Bmp->Canvas->Pixels[j][i+2] == clBlack;
Bmp->Canvas->Pixels[j][i+3] == clBlack;
Bmp->Canvas->Pixels[j+1][i+1] == clBlack;
Bmp->Canvas->Pixels[j+1][i+2] == clBlack;
Bmp->Canvas->Pixels[j+1][i+3] == clBlack;
Bmp->Canvas->Pixels[j+2][i+1] == clBlack;
Bmp->Canvas->Pixels[j+2][i+2] == clBlack;
Bmp->Canvas->Pixels[j+2][i+3] == clBlack;
Bmp->Canvas->Pixels[j+3][i+1] == clBlack;
Bmp->Canvas->Pixels[j+3][i+2] == clBlack;
Bmp->Canvas->Pixels[j+3][i+3] == clBlack;
}
}
} Image2->Picture->Assign(Bmp);
Image2->Show();
delete Bmp;
|
richtop
資深會員
發表:122 回覆:646 積分:468 註冊:2003-06-10
發送簡訊給我
|
keikojason 您好: 若依您的說明,覺得程式碼並沒有對4x4區塊作判斷,另外您把=誤打成==了。
底下改寫您的程式碼,不知是否對題?您且參考修改。
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Byte *ptr;
int r, g, b, pt;
float y,cr,cb;
Graphics::TBitmap *Bmp = new Graphics::TBitmap(); Bmp->Assign(Image1->Picture->Bitmap); Bmp->PixelFormat = pf24bit; for(int j=0; jHeight-4; j =4)
{
for(int i=0; iWidth-4; i =4)
{ pt = 0;
for (int blky=0; blky<4; blky )
{ ptr = (Byte *)Bmp->ScanLine[j blky];
for ( int blkx=0; blkx<4; blkx )
{ r = ptr[(i blkx)*3];
g = ptr[(i blkx)*3 1];
r = ptr[(i blkx)*3 2]; y = 0.299*r 0.587*g 0.114*b;
cr = 0.5*r-0.419*g-0.081*b 128;
cb = -0.169*r-0.332*g 0.5*b 128; if( (cr>75 && cr<110) && (cb>85 && cb<133) )
pt ;
}
}
if ( pt==16 )
{
Bmp->Canvas->Pixels[i ][j ] = clWhite;
Bmp->Canvas->Pixels[i 1][j ] = clWhite;
Bmp->Canvas->Pixels[i 2][j ] = clWhite;
Bmp->Canvas->Pixels[i 3][j ] = clWhite;
Bmp->Canvas->Pixels[i ][j 1] = clWhite;
Bmp->Canvas->Pixels[i ][j 2] = clWhite;
Bmp->Canvas->Pixels[i ][j 3] = clWhite;
Bmp->Canvas->Pixels[i 1][j 1] = clWhite;
Bmp->Canvas->Pixels[i 1][j 2] = clWhite;
Bmp->Canvas->Pixels[i 1][j 3] = clWhite;
Bmp->Canvas->Pixels[i 2][j 1] = clWhite;
Bmp->Canvas->Pixels[i 2][j 2] = clWhite;
Bmp->Canvas->Pixels[i 2][j 3] = clWhite;
Bmp->Canvas->Pixels[i 3][j 1] = clWhite;
Bmp->Canvas->Pixels[i 3][j 2] = clWhite;
Bmp->Canvas->Pixels[i 3][j 3] = clWhite; }
else
{
Bmp->Canvas->Pixels[i ][j ] = clBlack;
Bmp->Canvas->Pixels[i 1][j ] = clBlack;
Bmp->Canvas->Pixels[i 2][j ] = clBlack;
Bmp->Canvas->Pixels[i 3][j ] = clBlack;
Bmp->Canvas->Pixels[i ][j 1] = clBlack;
Bmp->Canvas->Pixels[i ][j 2] = clBlack;
Bmp->Canvas->Pixels[i ][j 3] = clBlack;
Bmp->Canvas->Pixels[i 1][j 1] = clBlack;
Bmp->Canvas->Pixels[i 1][j 2] = clBlack;
Bmp->Canvas->Pixels[i 1][j 3] = clBlack;
Bmp->Canvas->Pixels[i 2][j 1] = clBlack;
Bmp->Canvas->Pixels[i 2][j 2] = clBlack;
Bmp->Canvas->Pixels[i 2][j 3] = clBlack;
Bmp->Canvas->Pixels[i 3][j 1] = clBlack;
Bmp->Canvas->Pixels[i 3][j 2] = clBlack;
Bmp->Canvas->Pixels[i 3][j 3] = clBlack;
}
}
} Graphics::TBitmap *bmp2 = Image2->Picture->Bitmap;
bmp2->PixelFormat = pf24bit;
bmp2->Width = Bmp->Width >> 2;
bmp2->Height= Bmp->Height >> 2;
int index, idxRow, value;
Byte * ptr2;
idxRow = 0;
for (int y=0; yHeight-4; y =4)
{ ptr = (Byte *) Bmp->ScanLine[y];
ptr2 = (Byte *) bmp2->ScanLine[idxRow];
index = 0;
for (int x=0; xWidth-4; x =4)
{ if ( ptr[x*3]==0 ) // clBlack
value = 0;
else value = 255;
ptr2[index ] = value;
ptr2[index 1] = value;
ptr2[index 2] = value;
index = 3;
}
idxRow ;
} //Image2->Picture->Assign(Bmp);
Image2->Show();
delete Bmp;
} RichTop 敬上 =====*****
把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題!
=====#####
|
keikojason
初階會員
發表:37 回覆:63 積分:45 註冊:2004-05-10
發送簡訊給我
|
richtop前輩您好:
再請問前輩,如果要知道在原圖二值化有16點都是在範圍為白色,那如果沒有為黑色,那如果界與之間0~16用灰色,顯示在原圖大小的二值化圖上,這樣方式是不是會變的很複雜呢?例如下面圖示320*240那要怎樣修改呢?我有試著改過就是怪怪的><....以下是我用的...
還有下面是我對前輩撰寫的部分不懂~~請前輩指教 ..謝謝...^^
< src="http://delphi.ktop.com.tw/loadfile.php?TOPICID=19268293&CC=430927">
for(int j=0; jHeight-4; j+=4)<==這為什麼-4又+4呢?我有是過-4去掉沒有差別呢?請問為什麼呢?
for(int i=0; iWidth-4; i+=4) bmp2->Width = Bmp->Width >> 2;<==為什麼要>>2是怕超出範圍嘛
bmp2->Height= Bmp->Height >> 2;
Graphics::TBitmap *Bmp = new Graphics::TBitmap();
Bmp->Assign(Image1->Picture->Bitmap);
for(j=0;jHeight;j++)
{
ptr = (Byte *)Bmp->ScanLine[j]; for(i=0;iWidth;i++)
{
b=ptr[i*3];
g=ptr[i*3+1];
r=ptr[i*3+2]; y = 0.299*r+0.587*g+0.114*b;
cr = 0.5*r-0.419*g-0.081*b+128;
cb = -0.169*r-0.332*g+0.5*b+128;
if ((ptr[i*3]==121)&&(ptr[i*3+1]==120)&&(ptr[i*3+2])==121)
{
Bmp->Canvas->Pixels[i ][j ] = clGray;
Bmp->Canvas->Pixels[i+1][j ] = clGray;
Bmp->Canvas->Pixels[i+2][j ] = clGray;
Bmp->Canvas->Pixels[i+3][j ] = clGray;
Bmp->Canvas->Pixels[i ][j+1] = clGray;
Bmp->Canvas->Pixels[i ][j+2] = clGray;
Bmp->Canvas->Pixels[i ][j+3] = clGray;
Bmp->Canvas->Pixels[i+1][j+1] = clGray;
Bmp->Canvas->Pixels[i+1][j+2] = clGray;
Bmp->Canvas->Pixels[i+1][j+3] = clGray;
Bmp->Canvas->Pixels[i+2][j+1] = clGray;
Bmp->Canvas->Pixels[i+2][j+2] = clGray;
Bmp->Canvas->Pixels[i+2][j+3] = clGray;
Bmp->Canvas->Pixels[i+3][j+1] = clGray;
Bmp->Canvas->Pixels[i+3][j+2] = clGray;
Bmp->Canvas->Pixels[i+3][j+3] = clGray;
}
else
{
if(ptr[i*3]==0)
Bmp->Canvas->Pixels[i ][j ] = clBlack;
Bmp->Canvas->Pixels[i+1][j ] = clBlack;
Bmp->Canvas->Pixels[i+2][j ] = clBlack;
Bmp->Canvas->Pixels[i+3][j ] = clBlack;
Bmp->Canvas->Pixels[i ][j+1] = clBlack;
Bmp->Canvas->Pixels[i ][j+2] = clBlack;
Bmp->Canvas->Pixels[i ][j+3] = clBlack;
Bmp->Canvas->Pixels[i+1][j+1] = clBlack;
Bmp->Canvas->Pixels[i+1][j+2] = clBlack;
Bmp->Canvas->Pixels[i+1][j+3] = clBlack;
Bmp->Canvas->Pixels[i+2][j+1] = clBlack;
Bmp->Canvas->Pixels[i+2][j+2] = clBlack;
Bmp->Canvas->Pixels[i+2][j+3] = clBlack;
Bmp->Canvas->Pixels[i+3][j+1] = clBlack;
Bmp->Canvas->Pixels[i+3][j+2] = clBlack;
Bmp->Canvas->Pixels[i+3][j+3] = clBlack;
}
else
{
ptr[i*3]=0;
Bmp->Canvas->Pixels[i ][j ] = clWhite;
Bmp->Canvas->Pixels[i+1][j ] = clWhite;
Bmp->Canvas->Pixels[i+2][j ] = clWhite;
Bmp->Canvas->Pixels[i+3][j ] = clWhite;
Bmp->Canvas->Pixels[i ][j+1] = clWhite;
Bmp->Canvas->Pixels[i ][j+2] = clWhite;
Bmp->Canvas->Pixels[i ][j+3] = clWhite;
Bmp->Canvas->Pixels[i+1][j+1] = clWhite;
Bmp->Canvas->Pixels[i+1][j+2] = clWhite;
Bmp->Canvas->Pixels[i+1][j+3] = clWhite;
Bmp->Canvas->Pixels[i+2][j+1] = clWhite;
Bmp->Canvas->Pixels[i+2][j+2] = clWhite;
Bmp->Canvas->Pixels[i+2][j+3] = clWhite;
Bmp->Canvas->Pixels[i+3][j+1] = clWhite;
Bmp->Canvas->Pixels[i+3][j+2] = clWhite;
Bmp->Canvas->Pixels[i+3][j+3] = clWhite; }
}
}
Image3->Picture->Assign(Bmp);
Image3->Show();
delete Bmp;
發表人 - keikojason 於 2004/12/15 13:10:14
|
JerryKuo
版主
發表:42 回覆:571 積分:322 註冊:2003-03-10
發送簡訊給我
|
引言:
各位大大前輩好:
不知道那位前輩可以為小弟解惑..< >在下會細心聆聽
在下是新手多多學習中< >
keikojason你好: 不妨參考richtop前輩的做法做看看。
|
keikojason
初階會員
發表:37 回覆:63 積分:45 註冊:2004-05-10
發送簡訊給我
|
richtop前輩你好:
之前用的算OK!有點問像問前輩,我還有另外一個問題,假設我要在一個二值化的圖像如圖(Img1)中,如果在16點全部都是白色點(255,)顯示在另一張圖像(Img2)一樣是白色,16點都是黑色在(Img2)圖像一樣是黑色點,若介於16至0之間的點,以灰色表示...最下面是我用的程式,但出來圖和原圖還是一樣,請問前輩哪有問題啊!是方式錯誤嘛?~~ 還有以下是我對前輩先前的程式不了解~~不知道<>藍色部分>有什麼作用:
< src="http://delphi.ktop.com.tw/download/upload\61560_06-1.bmp">
for(int j=0; jHeight-4; j =4) <=為什麼-4又 4,我有試著去除-4好像沒有差異結果一樣
for(int i=0; iWidth-4; i =4)
bmp2->Width = Bmp->Width >> 2; <=這視為什麼要>>2什麼原因呢?
bmp2->Height= Bmp->Height >> 2;
Graphics::TBitmap *Bmp = new Graphics::TBitmap();
Bmp->Assign(Image1->Picture->Bitmap);
int pt;
for(j=0;jHeight-4;j =4)
{
ptr = (Byte *)Bmp->ScanLine[j]; for(i=0;iWidth-4;i =4)
{
pt=0;
for (int blky=0; blky<4; blky )
{
ptr = (Byte *)Bmp->ScanLine[j blky];
for ( int blkx=0; blkx<4; blkx )
{ r = ptr[(i blkx)*3];
g = ptr[(i blkx)*3 1];
r = ptr[(i blkx)*3 2]; y = 0.299*r 0.587*g 0.114*b;
cr = 0.5*r-0.419*g-0.081*b 128;
cb = -0.169*r-0.332*g 0.5*b 128;
pt ; if(pt<16&&pt>0)
{
Bmp->Canvas->Pixels[i ][j ] == clGray;
Bmp->Canvas->Pixels[i ][j 1] == clGray;
Bmp->Canvas->Pixels[i ][j 2] == clGray;
Bmp->Canvas->Pixels[i ][j 3] == clGray;
Bmp->Canvas->Pixels[i 1][j ] == clGray;
Bmp->Canvas->Pixels[i 2][j ] == clGray;
Bmp->Canvas->Pixels[i 3][j ] == clGray;
Bmp->Canvas->Pixels[i 1][j 1] == clGray;
Bmp->Canvas->Pixels[i 2][j 1] == clGray;
Bmp->Canvas->Pixels[i 3][j 1] == clGray;
Bmp->Canvas->Pixels[i 1][j 2] == clGray;
Bmp->Canvas->Pixels[i 2][j 2] == clGray;
Bmp->Canvas->Pixels[i 3][j 2] == clGray;
Bmp->Canvas->Pixels[i 1][j 3] == clGray;
Bmp->Canvas->Pixels[i 2][j 3] == clGray;
Bmp->Canvas->Pixels[i 3][j 3] == clGray;
}
else
{
if(pt=16)
{
Bmp->Canvas->Pixels[i ][j ] == clWhite;
...
....
Bmp->Canvas->Pixels[i 3][j 3] == clWhite;
}
else
{ pt=0;
Bmp->Canvas->Pixels[i ][j ] == clBlack;
...
....
Bmp->Canvas->Pixels[i 3][j 3] == clBlack;
}
}
}
}
}
}
Image2->Picture->Assign(Bmp);
Image2->Show();
delete Bmp;
}
|
richtop
資深會員
發表:122 回覆:646 積分:468 註冊:2003-06-10
發送簡訊給我
|
keikojason 您好: 覺得您在計算pt時的條件判斷,會導致點數有相當的數量變化。
所以無法精確測驗您的結果。 引言:
richtop前輩你好:
之前用的算OK!有點問像問前輩,我還有另外一個問題,假設我要在一個二值化的圖像如圖(Img1)中,如果在16點全部都是白色點(255,)顯示在另一張圖像(Img2)一樣是白色,16點都是黑色在(Img2)圖像一樣是黑色點,若介於16至0之間的點,以灰色表示...最下面是我用的程式,但出來圖和原圖還是一樣,請問前輩哪有問題啊!是方式錯誤嘛?~~ 還有以下是我對前輩先前的程式不了解~~不知道<>藍色部分>有什麼作用:
< src="http://delphi.ktop.com.tw/download/upload\61560_06-1.bmp">
for(int j=0; jHeight-4; j =4) <=為什麼-4又 4,我有試著去除-4好像沒有差異結果一樣
//=== -4是怕超出邊界,因為您是想把4x4當成一點。
for(int i=0; iWidth-4; i =4)
bmp2->Width = Bmp->Width >> 2; <=這視為什麼要>>2什麼原因呢?
//=== >>2 是右移兩個位元,也就是除以4,希望速度快一點。
bmp2->Height= Bmp->Height >> 2;
r = ptr[(i blkx)*3]; // 此處的r應改為b,我寫錯了!
g = ptr[(i blkx)*3 1];
r = ptr[(i blkx)*3 2];
...
}
else
{
if(pt=16) 此處明顯有誤,pt==16
{
Bmp->Canvas->Pixels[i ][j ] == clWhite;
...
....
Bmp->Canvas->Pixels[i 3][j 3] == clWhite;
RichTop 敬上 =====*****
把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題!
=====#####
|
keikojason
初階會員
發表:37 回覆:63 積分:45 註冊:2004-05-10
發送簡訊給我
|
以上這圖是要用的原始二值圖,前輩說的我有改過 r改為b囉!效果都一樣沒有變呢?處理結果和原圖一樣。 一個二值化的圖(Img1),如果在16點全部都是白色點(255),顯示在另一張圖像(Img2)一樣是白色,16點都是黑色在(Img2)圖像一樣是黑色點,若介於16至0之間的點,以灰色表示這是我要呈現圖像的意思....
那下面那行為什麼有誤ㄋ呢?..是因為我想的邏輯有誤嘛!!那我要怎樣用呢?
{
if(pt==16) <==為什麼有誤呢? pt=16與pt==16效果一樣
{
Bmp->Canvas->Pixels[i ][j ] == clWhite;
...
....
Bmp->Canvas->Pixels[i 3][j 3] == clWhite;
發表人 - keikojason 於 2004/12/22 16:38:56
|
richtop
資深會員
發表:122 回覆:646 積分:468 註冊:2003-06-10
發送簡訊給我
|
引言:
以上這圖是要用的原始二值圖,前輩說的我有改過r改為b囉!效果都一樣沒有變呢?處理結果和原圖一樣。 一個二值化的圖(Img1),如果在16點全部都是白色點(255),顯示在另一張圖像(Img2)一樣是白色,16點都是黑色在(Img2)圖像一樣是黑色點,若介於16至0之間的點,以灰色表示這是我要呈現圖像的意思....
那下面那行為什麼有誤ㄋ呢?..是因為我想的邏輯有誤嘛!!那我要怎樣用呢?
{
if(pt==16) <==為什麼有誤呢? pt=16與pt==16效果一樣
pt=16會將的值設為16,再據以判斷時一定成立,只是您的結果似乎沒有跑到這一行。
{
Bmp->Canvas->Pixels[i ][j ] == clWhite;
...
....
Bmp->Canvas->Pixels[i+3][j+3] == clWhite;
發表人 - keikojason 於 2004/12/22 16:38:56
如果如您所說,已經化為二值化圖形的話,可用下列方式判斷:
for(int j=0; jHeight-4; j+=4)
{
for(int i=0; iWidth-4; i+=4)
{ pt = 0;
for (int blky=0; blky<4; blky++)
{ ptr = (Byte *)Bmp->ScanLine[j+blky];
for ( int blkx=0; blkx<4; blkx++)
{ b = ptr[(i+blkx)*3];
g = ptr[(i+blkx)*3+1];
r = ptr[(i+blkx)*3+2]; /* 註解部分為您原先的判斷方式
y = 0.299*r+0.587*g+0.114*b;
cr = 0.5*r-0.419*g-0.081*b+128;
cb = -0.169*r-0.332*g+0.5*b+128; if( (cr>75 && cr<110) && (cb>85 && cb<133) )
*/ if ( r==255 && g==255 && b==255 )
pt ++;
}
} RichTop 敬上 =====*****
把數學當工具,可以解決問題;將數學變能力,能夠發現並解決問題!
=====#####
|
keikojason
初階會員
發表:37 回覆:63 積分:45 註冊:2004-05-10
發送簡訊給我
|
引言:
/* 註解部分為您原先的判斷方式
y = 0.299*r 0.587*g 0.114*b;
cr = 0.5*r-0.419*g-0.081*b 128;
cb = -0.169*r-0.332*g 0.5*b 128; if( (cr>75 && cr<110) && (cb>85 && cb<133) )
*/ if ( r==255 && g==255 && b==255 )
pt ;
}
}
請問前輩您說的"原先的判斷方式"是指那個判斷式呢?是指下面判斷式嗎?如果是的話,好想沒有辦法和前輩上傳那張圖小圖一樣~~~
另外再請問前輩,像在一開始問的問題(最上面第一個)<>將這些點顯示在另一張圖中(會比原圖變小),形成縮小的二值化圖>,那如果我要將結果顯示 class="code">
if(pt=16)
{
Bmp->Canvas->Pixels[i ][j ] == clWhite;
...
....
Bmp->Canvas->Pixels[i 3][j 3] == clWhite;
}
else
{ pt=0;
Bmp->Canvas->Pixels[i ][j ] == clBlack;
...
....
Bmp->Canvas->Pixels[i 3][j 3] == clBlack;
}
[/code]
|