对一个黑白二值图象中某个已知的黑色区域计算周长,区域象素已被分离,并存入一个X,Y轴坐标的二维数柱中,现在只需按得到的象素点,计算周长,可是不知道算法!有提供算法的,给N分,有原代码的更OK!

解决方案 »

  1.   

    对于黑白二值图像我倒是有个想法,我试验过,你可以试试看。
    对图像做边缘处理。我试过以下两种算法: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.
      

  2.   

    上面那个窗体的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.
      

  3.   

    你看一下这个吧
    http://expert.csdn.net/Expert/topic/2240/2240415.xml?temp=.2414972
      

  4.   

    另外,我为了试验方便,buf1定义为256*256的图像,因此要用它打开256*256的图像,或者修改它的定义。如果需要这个程序的源代码可以留下mail,我发给你。
      

  5.   

    xiexie
    i love all of you!
      

  6.   

    my email is :[email protected]
    thank you very much!!!!!!!!!!!!
      

  7.   

    要较精确的计算周长,可以通过计算物体边界上相邻象素的中心距的累加和得到,也可以从边界链码中计算得到。
    可参考 章毓晋,图象工程 (上册) 图象处理和分析,清华大学出版社, 北京,1999 
    里面有提到的。
    公式不好输,
    你看看http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter16/chapt16_ahz.htm
    第一节,物体测量
    面积与周长
      

  8.   

    http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter16/chapt16_ahz.htm
    为何这个网址进不去?
      

  9.   

    穷举周围所有点
     连接的时候周长c,+=x,或+=y 又或 +=sqrl(x*x+y*y)
      不知道行不行个人意见……