对于黑白二值图像我倒是有个想法,我试验过,你可以试试看。 对图像做边缘处理。我试过以下两种算法:Roberts梯度算子和Laplace算子。 结果是Roberts梯度算子可以很好的描绘出黑色区域的边缘,处理后,图像变为黑色背景,而原图像黑色区域的边缘用白色象素表示。而Laplace算子运算后,虽然也可以描绘出黑色区域的边缘,但是在整幅图像的边缘出现了噪声。推荐你使用Roberts梯度算子。 经过Roberts梯度算子运算,统计运算后图像的白色象素个数就可以近似黑色区域的周长了(如果是不规则图形的话,只能近似了)。 你试试看吧,应该可以满足你的要求。 注:只对256Bit灰度图像处理。如果需要它的源码,可以留下mail,我会给你发一份编译通过的,包含了Roberts梯度算子和Laplace算子的程序源码。type buf1为运算的图像矩阵 robert算子程序如下,oldbuf为输入图像,newbuf为输出图像,也就是背景为黑色,边缘为白色象素的图像。 imgwidth,imglenth为图像的宽,长。 MDI,两个子窗口分别显示处理前后的图像 //子窗体 unit SharpChd;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls;type Buf1=array[0..255,0..255]of byte;//图像数据 TSharpform2 = class(TForm) Image1: TImage; procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } Current:Tpoint; procedure readimg(Var imgbuf:buf1); procedure Showimg(Var newbuf:buf1); procedure open(const afilename:string); procedure creat(var left,top,height,width:word); end;var Sharpform2: TSharpform2; Bitmap:TBitmap; Filename:string; implementation uses Sharpmain; {$R *.DFM} //读取图像数据 procedure TSharpform2.readimg(Var imgbuf: buf1); Var i,j:word; begin for i := 0 to Imgwidth-1 do for j := 0 to Imglenth-1 do imgbuf[i][j] := GetBValue(bitmap.Canvas.pixels[i, j]); end;//显示图像 procedure TSharpform2.Showimg(Var newbuf:buf1); Var i,j:word; begin for i := 0 to Imgwidth-1 do for j := 0 to Imglenth-1 do bitmap.Canvas.pixels[i,j]:=RGB(newbuf[i][j],newbuf[i][j],newbuf[i,j]); image1.Picture.Graphic:=Bitmap; bitmap.free; end;procedure TSharpform2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;procedure TSharpform2.open(const afilename:string); begin Filename := Afilename; image1.picture.loadfromfile(Filename); Caption := Filename; ImgWidth := image1.picture.width; Imglenth := image1.picture.height; end;procedure TSharpform2.creat(var left, top, height, width: word); begin Sharpform2 := TSharpform2.create(self); Sharpform2.Left := ImgWidth+ImgWidth div left; Sharpform2.Top := Sharpform1.top div top; Sharpform2.ClientHeight := Imglenth; Sharpform2.ClientWidth := Imgwidth; end;end.
上面那个窗体的Image1MouseMove申明去掉,本来要用来显示图像坐标的。 //主窗体 unit SharpMain;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls,SharpChd;type TSharpform1 = class(TForm) Button1: TButton; Button2: TButton; OpenDialog1: TOpenDialog; Panel1: TPanel; Button3: TButton; Button4: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormActivate(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var oldbuf ,newbuf:buf1; Sharpform1: TSharpform1; CurrentFile, currentcaption:string; Imgwidth, Imglenth:word; implementation{$R *.DFM} //Roberts算子 procedure Rob_flt(var oldbuf,newbuf:buf1); Var reg,i,j:word; begin for i:=0 to imgwidth-2 do for j:=0 to imglenth-2 do begin newbuf[i][j]:=abs( oldbuf[i][j]-oldbuf[i+1][j+1] )+ abs( oldbuf[i+1][j]-oldbuf[i][j+1] ); end; end;//Laplace算子 procedure Lap_flt(var oldbuf,newbuf:buf1); Var i,j:word; reg:integer; begin for i:=0 to imgwidth-2 do for j:=0 to imglenth-2 do begin newbuf[i][j]:=5*oldbuf[i][j]- abs( oldbuf[i-1][j]-oldbuf[i+1][j]- oldbuf[i][j-1]-oldbuf[i][j+1] ); end; end;procedure TSharpform1.Button1Click(Sender: TObject); begin Button2.Enabled:=True; Button3.Enabled:=True; OpenDialog1.InitialDir:='C:\'; OpenDialog1.Filter:='BMP Files (*.bmp)|*.bmp'; if opendialog1.execute then begin Sharpform2:=TSharpform2.Create(self); Sharpform2.open(opendialog1.filename); Sharpform2.Left:=Sharpform1.left div 5; Sharpform2.Top:=Sharpform1.Top div 3; Sharpform2.ClientHeight:=Imglenth; Sharpform2.ClientWidth:=Imgwidth; end; end;procedure TSharpform1.Button2Click(Sender: TObject); var left,top:word; begin Button3.Enabled:=False; left:=2;top:=3; bitmap:=activeMDIChild.GetFormImage; Sharpform2.readimg(oldbuf); Rob_flt(oldbuf,newbuf); Sharpform2.creat(left,top,imglenth,imgwidth); Sharpform2.caption:='Robert_image'; Sharpform2.showimg(newbuf); end;procedure TSharpform1.Button3Click(Sender: TObject); var left,top:word; begin Button2.Enabled:=False; left:=4;top:=6; bitmap:=activeMDIChild.GetFormImage; Sharpform2.readimg(oldbuf); lap_flt(oldbuf,newbuf); Sharpform2.creat(left,top,imglenth,imgwidth); Sharpform2.caption:='Laplac_image'; Sharpform2.showimg(newbuf); end;procedure TSharpform1.FormActivate(Sender: TObject); begin if MDIChildCount>0 then begin Button2.Enabled:=True; Button3.Enabled:=True; end else begin Button2.Enabled:=False; Button3.Enabled:=False; end; end;procedure TSharpform1.Button4Click(Sender: TObject); begin Close; end;end.
对图像做边缘处理。我试过以下两种算法:Roberts梯度算子和Laplace算子。
结果是Roberts梯度算子可以很好的描绘出黑色区域的边缘,处理后,图像变为黑色背景,而原图像黑色区域的边缘用白色象素表示。而Laplace算子运算后,虽然也可以描绘出黑色区域的边缘,但是在整幅图像的边缘出现了噪声。推荐你使用Roberts梯度算子。
经过Roberts梯度算子运算,统计运算后图像的白色象素个数就可以近似黑色区域的周长了(如果是不规则图形的话,只能近似了)。
你试试看吧,应该可以满足你的要求。
注:只对256Bit灰度图像处理。如果需要它的源码,可以留下mail,我会给你发一份编译通过的,包含了Roberts梯度算子和Laplace算子的程序源码。type buf1为运算的图像矩阵
robert算子程序如下,oldbuf为输入图像,newbuf为输出图像,也就是背景为黑色,边缘为白色象素的图像。
imgwidth,imglenth为图像的宽,长。
MDI,两个子窗口分别显示处理前后的图像
//子窗体
unit SharpChd;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls;type
Buf1=array[0..255,0..255]of byte;//图像数据
TSharpform2 = class(TForm)
Image1: TImage;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
Current:Tpoint;
procedure readimg(Var imgbuf:buf1);
procedure Showimg(Var newbuf:buf1);
procedure open(const afilename:string);
procedure creat(var left,top,height,width:word);
end;var
Sharpform2: TSharpform2;
Bitmap:TBitmap;
Filename:string;
implementation
uses Sharpmain;
{$R *.DFM}
//读取图像数据
procedure TSharpform2.readimg(Var imgbuf: buf1);
Var
i,j:word;
begin
for i := 0 to Imgwidth-1 do
for j := 0 to Imglenth-1 do
imgbuf[i][j] := GetBValue(bitmap.Canvas.pixels[i, j]);
end;//显示图像
procedure TSharpform2.Showimg(Var newbuf:buf1);
Var
i,j:word;
begin
for i := 0 to Imgwidth-1 do
for j := 0 to Imglenth-1 do
bitmap.Canvas.pixels[i,j]:=RGB(newbuf[i][j],newbuf[i][j],newbuf[i,j]);
image1.Picture.Graphic:=Bitmap;
bitmap.free;
end;procedure TSharpform2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;procedure TSharpform2.open(const afilename:string);
begin
Filename := Afilename;
image1.picture.loadfromfile(Filename);
Caption := Filename;
ImgWidth := image1.picture.width;
Imglenth := image1.picture.height;
end;procedure TSharpform2.creat(var left, top, height, width: word);
begin
Sharpform2 := TSharpform2.create(self);
Sharpform2.Left := ImgWidth+ImgWidth div left;
Sharpform2.Top := Sharpform1.top div top;
Sharpform2.ClientHeight := Imglenth;
Sharpform2.ClientWidth := Imgwidth;
end;end.
//主窗体
unit SharpMain;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls,SharpChd;type
TSharpform1 = class(TForm)
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
Panel1: TPanel;
Button3: TButton;
Button4: TButton; procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
oldbuf ,newbuf:buf1;
Sharpform1: TSharpform1;
CurrentFile, currentcaption:string;
Imgwidth, Imglenth:word;
implementation{$R *.DFM}
//Roberts算子
procedure Rob_flt(var oldbuf,newbuf:buf1);
Var
reg,i,j:word;
begin
for i:=0 to imgwidth-2 do
for j:=0 to imglenth-2 do
begin
newbuf[i][j]:=abs( oldbuf[i][j]-oldbuf[i+1][j+1] )+
abs( oldbuf[i+1][j]-oldbuf[i][j+1] );
end;
end;//Laplace算子
procedure Lap_flt(var oldbuf,newbuf:buf1);
Var
i,j:word;
reg:integer;
begin for i:=0 to imgwidth-2 do
for j:=0 to imglenth-2 do
begin
newbuf[i][j]:=5*oldbuf[i][j]-
abs( oldbuf[i-1][j]-oldbuf[i+1][j]-
oldbuf[i][j-1]-oldbuf[i][j+1] );
end;
end;procedure TSharpform1.Button1Click(Sender: TObject);
begin
Button2.Enabled:=True;
Button3.Enabled:=True;
OpenDialog1.InitialDir:='C:\';
OpenDialog1.Filter:='BMP Files (*.bmp)|*.bmp';
if opendialog1.execute then
begin
Sharpform2:=TSharpform2.Create(self);
Sharpform2.open(opendialog1.filename);
Sharpform2.Left:=Sharpform1.left div 5;
Sharpform2.Top:=Sharpform1.Top div 3;
Sharpform2.ClientHeight:=Imglenth;
Sharpform2.ClientWidth:=Imgwidth;
end;
end;procedure TSharpform1.Button2Click(Sender: TObject);
var
left,top:word;
begin
Button3.Enabled:=False;
left:=2;top:=3;
bitmap:=activeMDIChild.GetFormImage;
Sharpform2.readimg(oldbuf);
Rob_flt(oldbuf,newbuf);
Sharpform2.creat(left,top,imglenth,imgwidth);
Sharpform2.caption:='Robert_image';
Sharpform2.showimg(newbuf);
end;procedure TSharpform1.Button3Click(Sender: TObject);
var
left,top:word;
begin
Button2.Enabled:=False;
left:=4;top:=6;
bitmap:=activeMDIChild.GetFormImage;
Sharpform2.readimg(oldbuf);
lap_flt(oldbuf,newbuf);
Sharpform2.creat(left,top,imglenth,imgwidth);
Sharpform2.caption:='Laplac_image';
Sharpform2.showimg(newbuf);
end;procedure TSharpform1.FormActivate(Sender: TObject);
begin
if MDIChildCount>0
then begin
Button2.Enabled:=True;
Button3.Enabled:=True;
end
else begin
Button2.Enabled:=False;
Button3.Enabled:=False;
end;
end;procedure TSharpform1.Button4Click(Sender: TObject);
begin
Close;
end;end.
http://expert.csdn.net/Expert/topic/2240/2240415.xml?temp=.2414972
i love all of you!
thank you very much!!!!!!!!!!!!
可参考 章毓晋,图象工程 (上册) 图象处理和分析,清华大学出版社, 北京,1999
里面有提到的。
公式不好输,
你看看http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter16/chapt16_ahz.htm
第一节,物体测量
面积与周长
为何这个网址进不去?
连接的时候周长c,+=x,或+=y 又或 +=sqrl(x*x+y*y)
不知道行不行个人意见……