上一篇:TWebBrowser控件禁用鼠标右键
下一篇:Delphi获取图片的真实类型

Delphi二值图像除杂点(噪点)

发布于: 2013/1/24 10:31:11   |  发布在: Delphi文章   |  点击:

本文使用的是计算图像的联通分量的方法,首先扫描二值图像所有象素点,如果为黑色点则加入相关联通分量;如果该点连接多个联通分量,则合并这些联通分量;如果该点不属于任何联通分量,则新建一个联通分量。最后删除(将像素设置为白色)点数小于或等于设定值的联通分量(杂点或者说噪点)。

procedure ClearPicNoise(Bmp: TBitmap; N: Integer);
//CodeBy: http://www.learnew.com
type
   PList = ^TList;
   PPoint = ^TPoint;
var
   UnionList: TList;
   aUnion: PList;
   aPoint: PPoint;
   X, Y: Integer;
   P: PByteArray;
   procedure AddToUnion(X1, Y1: Integer);
   var
      L1, L2, L3: PList;
      P1, P2: PPoint;
      i, j, k, iNo: Integer;
   begin
      New(P1);
      P1.X := X1; P1.Y := Y1;
      iNo := -1;
      for i := 0 to UnionList.Count - 1 do
      begin
         L2 := UnionList.Items[i];
         for j :=0 to L2.Count - 1 do
         begin
            P2 := L2.Items[j];
            if (Abs(P2.X - X1) <= 1) and (Abs(P2.Y - Y1) <= 1) then //找到邻点
            begin
               if iNo < 0 then //加入联通分量
               begin
                  iNo := i;
                  L2.Add(P1);
               end else begin //合并到 iNo 号联通分量
                  L3 := UnionList.Items[iNo];
                  for k := 0 to L2.Count - 1 do L3.Add(L2.Items[k]);
                  L2.Clear;
               end;
               Break;
            end;
         end;
      end;
      if iNo < 0 then //没有找到相关联通分量
      begin
         New(L1); //新建联通分量
         L1^ := TList.Create;
         L1.Add(P1);
         UnionList.Add(L1);
      end;
   end;
begin
   UnionList := TList.Create;
   //统计图像联通分量
   for Y := 0 to Bmp.Height - 1 do
   begin
      P := Bmp.ScanLine[Y];
      for X := 0 to Bmp.Width - 1 do
         if (P[X*3] = 0) and (P[X*3+1] = 0) and (P[X*3+2] = 0) then//为黑色点
            AddToUnion(X, Y);
   end;
   //将点数小于等于N的联通分量(杂点)设置为白点
   for X := 0 to UnionList.Count - 1 do
   begin
      aUnion := UnionList.Items[X];
      for Y := 0 to aUnion.Count - 1 do
      begin
         aPoint := aUnion.Items[Y];
         if aUnion.Count <= N then  //杂点
            Bmp.Canvas.Pixels[aPoint.X, aPoint.Y] := RGB(255, 255, 255);
         Dispose(aPoint); //释放变量
      end;
      aUnion.Free; //释放变量
   end;
   UnionList.Free; //释放变量
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ClearPicNoise(Image1.Picture.Bitmap, 2);
end;

二值图像