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;

联系电话:
020-00000000
联系电话:
020-00000000
联系电话:
020-12345678