我想做图像的轮廓提取,针对256色的bmp图。
有什么固定的模式吗?有什么好的算法吗?
有什么固定的模式吗?有什么好的算法吗?
解决方案 »
- SQL datetime 时间间隔
- exe里的panel内动态加载form,如何建立2个dpk包文件?
- DBGrid的异常怎么捕捉呢?急!!!
- 数据库恢复错误
- 有可以实现文字复制功能的类似label的控件吗?
- query.edit出现了cannot modify a read_only dataset的错误是为什么呢》》
- 简单的问题!!!
- installshield东方版的密码是什么?
- 请教熟悉SQL的大虾:如何在存储过程中遍历一个表的所有数据?
- 有没有这样一个控件,它连接DBGrid,将DBGrid的内容输出到EXCE中
- 才开始学模式,自己写的一个工厂方法,大家看看,看谁能用拿去用吧
- [转贴]很现实,也感人。MM与IT GG的对话!
====================================================================
下面是使用拉普拉斯算子对图像提取边缘的代码,运行后能够实现预想的效果,但是很费时!
大家能否给出优化代码以提高处理速度的建议吗?
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
int oper[3][3] = {{0,1,0},{1,-4,1},{0,1,0}};//拉普拉斯模板
H_Filtering(Image1->Picture->Bitmap,Image1->Picture->Bitmap,oper);
}void H_Filtering(Graphics::TBitmap *srcBitmap,Graphics::TBitmap *dstBitmap,int oper[3][3])
{
int red,green,blue;
int w = srcBitmap->Width,
h = srcBitmap->Height;
Graphics::TBitmap *bitmap= new Graphics::TBitmap();
bitmap->Height = h;
bitmap->Width = w;
for(int i=1;i<w-1;i++){
for(int j=1;j<h-1;j++){
//分别对R、G、B分量进行计算
red =0;
green =0;
blue =0;
for(int u=-1;u<2;u++){
for(int v=-1;v<2;v++){
red += oper[u+1][v+1]*GetRValue(srcBitmap->Canvas->Pixels[i+u][j+v]);
green += oper[u+1][v+1]*GetGValue(srcBitmap->Canvas->Pixels[i+u][j+v]);
blue += oper[u+1][v+1]*GetBValue(srcBitmap->Canvas->Pixels[i+u][j+v]);
}
}
//以下六行程序确保得到的新颜色值在有效范围[0,255]之内
red = red<0?0:red;
red = red>255?255:red;
green = green<0?0:green;
green = green>255?255:green;
blue = blue<0?0:blue;
blue = blue>255?255:blue;
bitmap->Canvas->Pixels[i][j] = (TColor)RGB(red,green,blue);
}
}
//以下两个for循环用于重复边缘值
for(int i=0;i<w;i++){
bitmap->Canvas->Pixels[i][0]=srcBitmap->Canvas->Pixels[i][0];
bitmap->Canvas->Pixels[i][h-1]=srcBitmap->Canvas->Pixels[i][h-1];
}
for(int j=1;j<h-1;j++){
bitmap->Canvas->Pixels[0][j]=srcBitmap->Canvas->Pixels[0][j];
bitmap->Canvas->Pixels[w-1][j]=srcBitmap->Canvas->Pixels[w-1][j];
}
dstBitmap->Assign(bitmap);
delete bitmap;
}
=================================================================
慢的原因在于你使用了bitmap->Canvas->Pixels。应该用bitmap->Canvas->ScanLine[j]得到第j行像素的起始地质,再加上一个偏移量得到一个点的像素值。
var
b0: Tbitmap;
i, j: Integer;
p1, p2, p3, p4: pbyteArray;
begin
b0 := Tbitmap.Create;
b0.Assign(b1); //Copies a b1 bitmap image to the bitmap b0 object.
b0.PixelFormat := pf24bit;
b1.PixelFormat := pf24bit; //24 bit
for i := 1 to b0.Height - 2 do
begin
p1 := b0.ScanLine[i - 1];
p2 := b0.ScanLine[i];
p3 := b0.ScanLine[i + 1]; //scan b0 3 lines
p4 := b1.ScanLine[i];
for j := 1 to b0.Width - 2 do
begin
if (p2[3 * j + 2] = 0) and (p2[3 * j + 1] = 0) and (p2[3 * j] = 0) then
begin if ((p2[3 * (j - 1) + 2] = 0) and (p2[3 * (j - 1) + 1] = 0) and
(p2[3 * (j - 1)] = 0)) and //pre line
((p2[3 * (j + 1) + 2] = 0) and (p2[3 * (j + 1) + 1] = 0) and
(p2[3 * (j + 1)] = 0)) and //next line ((p1[3 * (j + 1) + 2] = 0) and (p1[3 * (j + 1) + 1] = 0) and
(p1[3 * (j + 1)] = 0)) and
((p1[3 * (j) + 2] = 0) and (p1[3 * (j) + 1] = 0) and (p1[3 * (j)]
= 0)) and
((p1[3 * (j - 1) + 2] = 0) and (p1[3 * (j - 1) + 1] = 0) and
(p1[3 * (j - 1)] = 0)) and ((p3[3 * (j - 1) + 2] = 0) and (p3[3 * (j - 1) + 1] = 0) and
(p3[3 * (j - 1)] = 0)) and
((p3[3 * (j) + 2] = 0) and (p3[3 * (j) + 1] = 0) and (p3[3 * (j)]
= 0)) and
((p3[3 * (j + 1) + 2] = 0) and (p3[3 * (j + 1) + 1] = 0) and
(p3[3 * (j + 1)] = 0)) then //0,0 to 2,2 nine points are black
begin
p4[3 * j + 2] := 255;
p4[3 * j + 1] := 255;
p4[3 * j] := 255; //while color
end;
end;
end;
end;
b0.Free;
end;
这是针对256色黑白图片的轮廓提起,主要是判断每个黑点的周围八个点的颜色。也许你可以根据你的实际应用作相应的改动。感谢网友yan的帮助!!!
procedure TMyPicture.Button5Click(Sender: TObject);
var
b0, b1: Tbitmap;
i, j: Integer;
p1, p2, p3, p4: pbyteArray;
begin
b0 := Tbitmap.Create;
b1 := Tbitmap.Create;
b0.Assign(Image1.Picture.Bitmap);
b1.Assign(Image1.Picture.Bitmap);
b0.PixelFormat := pf24bit;
b1.PixelFormat := pf24bit;
for i := 1 to b0.Height - 2 do
begin
p1 := b0.ScanLine[i - 1];
p2 := b0.ScanLine[i];
p3 := b0.ScanLine[i + 1];
p4 := b1.ScanLine[i];
for j := 1 to b0.Width - 2 do
begin
if (p2[3 * j + 2] = 0) and (p2[3 * j + 1] = 0) and (p2[3 * j] = 0) then
begin if ((p2[3 * (j - 1) + 2] = 0) and (p2[3 * (j - 1) + 1] = 0) and
(p2[3 * (j - 1)] = 0)) and
((p2[3 * (j + 1) + 2] = 0) and (p2[3 * (j + 1) + 1] = 0) and
(p2[3 * (j + 1)] = 0)) and
((p1[3 * (j + 1) + 2] = 0) and (p1[3 * (j + 1) + 1] = 0) and
(p1[3 * (j + 1)] = 0)) and
((p1[3 * (j) + 2] = 0) and (p1[3 * (j) + 1] = 0) and (p1[3 * (j)]
= 0)) and
((p1[3 * (j - 1) + 2] = 0) and (p1[3 * (j - 1) + 1] = 0) and
(p1[3 * (j - 1)] = 0)) and
((p3[3 * (j - 1) + 2] = 0) and (p3[3 * (j - 1) + 1] = 0) and
(p3[3 * (j - 1)] = 0)) and
((p3[3 * (j) + 2] = 0) and (p3[3 * (j) + 1] = 0) and (p3[3 * (j)]
= 0)) and
((p3[3 * (j + 1) + 2] = 0) and (p3[3 * (j + 1) + 1] = 0) and
(p3[3 * (j + 1)] = 0)) then
begin
p4[3 * j + 2] := 255;
p4[3 * j + 1] := 255;
p4[3 * j] := 255;
end;
end; end;
Image1.Picture.Bitmap.Assign(b1);
end;
b1.Free;
b0.Free;
end;