如果你说他们的大小差别较大那就很好解决,你可以看看《VB图象处理开发与实例》中 的扫描标号法计算图形面积和除去小面粒子的算法 这个函数是我的一个程序中用到的,这里我虽然求出了面积,但是 我的程序中不需要面积,所以没有返回 type tyArrayofbyte = Array of Byte; type ptyArrayofbyte = ^tyArrayofbyte;//功能:利用扫描标号法清除小面积粒子,并求出物体的面积//参数:lpSouceBuf 需要清除小面积粒子图像的数据数组指针,不包含图像头信息的数据 // lpDestBuf 清除小面积粒子后的图像数据数组指针 // dwImgWidth 图像宽度 // dwImgHeight图像高度//返回: 清除小面积粒子后的图像数据数组指针procedure CleanSmallArea_Scan(lpSouceBuf:ptyArrayofbyte;lpDestBuf:ptyArrayofbyte; dwImgWidth,dwImgHeight:DWORD);stdcall; var i, j,Rn,La,N,No,nHigh,m: DWORD; wBiaoRead :array of array of byte; WArea : array of DWORD; //面积 WSx : Array of DWORD; // 横坐标 WSy : Array of DWORD; //纵坐标 WEx : Array of DWORD; WLb : Array of DWORD; WK : Array of Integer; WKK : Array of DWORD; wFlag :boolean; begin SetLength(wBiaoRead,dwImgWidth,dwImgHeight); //得到图像数据 for j:=0 to dwImgHeight - 1 do begin for i:=0 to dwImgWidth -1 do begin m := (j*dwImgWidth+i)*3 ; wBiaoRead[i,j]:= lpSouceBuf^[m]; lpDestBuf^[m] := lpSouceBuf^[m]; //B lpDestBuf^[m+1] := lpSouceBuf^[m+1]; //G lpDestBuf^[m+2] := lpSouceBuf^[m+2]; //R end; end; //从左到右标号 La :=1; Rn :=0; SetLength(Wlb,Rn+1); SetLength(WSx,Rn+1); SetLength(WSy,Rn+1); SetLength(WEx,Rn+1); for i:=0 to dwImgHeight - 1 do begin wBiaoRead[dwImgWidth-1,i]:=255; //白色是物体,所以用白色标号 wFlag := false; for j:=0 to dwImgWidth -1 do begin if (not wFlag) and (wBiaoRead[j,i]=255) then begin nHigh := High(Wlb); if nHigh<Rn then begin SetLength(Wlb,Rn+1); SetLength(WSx,Rn+1); SetLength(WSy,Rn+1); end; Wlb[Rn] := La; WSx[Rn] := j; //得到横坐标 WSy[Rn] := i; //得到纵坐标 wFlag := true; end else if (wFlag) and (wBiaoRead[j,i]<>255) then begin nHigh := High(WEx); if nHigh<Rn then SetLength(WEx,Rn+1); WEx[Rn] := j-1; wFlag := false; Inc(Rn); Inc(La); end; end; // end for j end; //end for i //从左上到右下标号 for i :=0 to Rn-1 do begin for j:=0 to Rn-1 do begin if (WSy[i]-1=WSy[j]) then begin if (WSx[j]-1<=WSx[i])and (WEx[j]+1>=WSx[i]) then WLb[i] :=Wlb[j] else if (WSx[j]-1<=WEx[i])and (WEx[j]+1>=WEx[i]) then WLb[i] :=Wlb[j] else if (WSx[i]-1<=WSx[j])and (WEx[i]+1>=WEx[j]) then WLb[i] :=Wlb[j]; end;// if (WSy[i]-1=WSy[j]) end; //end for j end; // end for i //从右下到左上标号 for i :=Rn-1 to 0 do begin for j:=Rn-1 to 0 do begin if (WSy[i]-1=WSy[j]) then begin if (WSx[j]-1<=WSx[i])and (WEx[j]+1>=WSx[i]) then WLb[i] :=Wlb[j] else if (WSx[j]-1<=WEx[i])and (WEx[j]+1>=WEx[i]) then WLb[i] :=Wlb[j] else if (WSx[i]-1<=WSx[j])and (WEx[i]+1>=WSx[j]) then WLb[i] :=Wlb[j] else if (WSx[i]-1<=WEx[j])and (WEx[i]+1>=WEx[j]) then WLb[i] :=Wlb[j] ; end;// if (WSy[i]-1=WSy[j]) end; //end for j end; // end for i SetLength(wk,Rn); for i:=0 to Rn-1 do Wk[i]:=-1; for i:=0 to Rn-1 do Wk[Wlb[i]]:=wlb[i]; No :=0; SetLength(Wkk,No+1); for i:=0 to Rn-1 do begin if Wk[i]<>-1 then begin SetLength(Wkk,No+1); Wkk[No] := WK[i]; Inc(No); end; end; for i:=0 to No-1 do WK[Wkk[i]]:=i+1; for i:=0 to Rn - 1 do WLb[i] := Wk[Wlb[i]]; SetLength(WArea,No+1); for i:=0 to Rn - 1 do WArea[Wlb[i]] := WArea[Wlb[i]]+(WEx[i]-WSx[i]+1); //标号变色 for i :=0 to Rn - 1 do begin if WArea[Wlb[i]]>120 then //大于120的保留,否则置为黑色 begin for j := WSx[i] to WEx[i] do begin m := (Wsy[i]*dwImgWidth+j)*3 ; lpDestBuf^[m] := 255; lpDestBuf^[m+1] := 255; lpDestBuf^[m+2] := 255; end; end else begin for j := WSx[i] to WEx[i] do begin m := (Wsy[i]*dwImgWidth+j)*3 ; lpDestBuf^[m] := 0; lpDestBuf^[m+1] := 0; lpDestBuf^[m+2] := 0; end; end; end; SetLength(wBiaoRead,0); SetLength(Wsy,0); SetLength(WSx,0); SetLength(WEx,0); SetLength(Wlb,0); SetLength(WArea,0); SetLength(Wk,0); SetLength(WKK,0); end;
的扫描标号法计算图形面积和除去小面粒子的算法
这个函数是我的一个程序中用到的,这里我虽然求出了面积,但是
我的程序中不需要面积,所以没有返回
type tyArrayofbyte = Array of Byte;
type ptyArrayofbyte = ^tyArrayofbyte;//功能:利用扫描标号法清除小面积粒子,并求出物体的面积//参数:lpSouceBuf 需要清除小面积粒子图像的数据数组指针,不包含图像头信息的数据
// lpDestBuf 清除小面积粒子后的图像数据数组指针
// dwImgWidth 图像宽度
// dwImgHeight图像高度//返回: 清除小面积粒子后的图像数据数组指针procedure CleanSmallArea_Scan(lpSouceBuf:ptyArrayofbyte;lpDestBuf:ptyArrayofbyte;
dwImgWidth,dwImgHeight:DWORD);stdcall;
var
i, j,Rn,La,N,No,nHigh,m: DWORD;
wBiaoRead :array of array of byte;
WArea : array of DWORD; //面积
WSx : Array of DWORD; // 横坐标
WSy : Array of DWORD; //纵坐标
WEx : Array of DWORD;
WLb : Array of DWORD;
WK : Array of Integer;
WKK : Array of DWORD;
wFlag :boolean;
begin
SetLength(wBiaoRead,dwImgWidth,dwImgHeight);
//得到图像数据
for j:=0 to dwImgHeight - 1 do
begin
for i:=0 to dwImgWidth -1 do
begin
m := (j*dwImgWidth+i)*3 ;
wBiaoRead[i,j]:= lpSouceBuf^[m];
lpDestBuf^[m] := lpSouceBuf^[m]; //B
lpDestBuf^[m+1] := lpSouceBuf^[m+1]; //G
lpDestBuf^[m+2] := lpSouceBuf^[m+2]; //R
end;
end;
//从左到右标号
La :=1;
Rn :=0;
SetLength(Wlb,Rn+1);
SetLength(WSx,Rn+1);
SetLength(WSy,Rn+1);
SetLength(WEx,Rn+1);
for i:=0 to dwImgHeight - 1 do
begin
wBiaoRead[dwImgWidth-1,i]:=255; //白色是物体,所以用白色标号
wFlag := false;
for j:=0 to dwImgWidth -1 do
begin
if (not wFlag) and (wBiaoRead[j,i]=255) then
begin
nHigh := High(Wlb); if nHigh<Rn then
begin
SetLength(Wlb,Rn+1);
SetLength(WSx,Rn+1);
SetLength(WSy,Rn+1);
end;
Wlb[Rn] := La;
WSx[Rn] := j; //得到横坐标
WSy[Rn] := i; //得到纵坐标
wFlag := true;
end
else if (wFlag) and (wBiaoRead[j,i]<>255) then
begin
nHigh := High(WEx);
if nHigh<Rn then SetLength(WEx,Rn+1);
WEx[Rn] := j-1;
wFlag := false;
Inc(Rn);
Inc(La);
end;
end; // end for j
end; //end for i
//从左上到右下标号
for i :=0 to Rn-1 do
begin
for j:=0 to Rn-1 do
begin
if (WSy[i]-1=WSy[j]) then
begin
if (WSx[j]-1<=WSx[i])and (WEx[j]+1>=WSx[i]) then
WLb[i] :=Wlb[j]
else if (WSx[j]-1<=WEx[i])and (WEx[j]+1>=WEx[i]) then
WLb[i] :=Wlb[j]
else if (WSx[i]-1<=WSx[j])and (WEx[i]+1>=WEx[j]) then
WLb[i] :=Wlb[j];
end;// if (WSy[i]-1=WSy[j])
end; //end for j
end; // end for i
//从右下到左上标号
for i :=Rn-1 to 0 do
begin
for j:=Rn-1 to 0 do
begin
if (WSy[i]-1=WSy[j]) then
begin
if (WSx[j]-1<=WSx[i])and (WEx[j]+1>=WSx[i]) then
WLb[i] :=Wlb[j]
else if (WSx[j]-1<=WEx[i])and (WEx[j]+1>=WEx[i]) then
WLb[i] :=Wlb[j]
else if (WSx[i]-1<=WSx[j])and (WEx[i]+1>=WSx[j]) then
WLb[i] :=Wlb[j]
else if (WSx[i]-1<=WEx[j])and (WEx[i]+1>=WEx[j]) then
WLb[i] :=Wlb[j] ;
end;// if (WSy[i]-1=WSy[j])
end; //end for j
end; // end for i
SetLength(wk,Rn);
for i:=0 to Rn-1 do Wk[i]:=-1;
for i:=0 to Rn-1 do Wk[Wlb[i]]:=wlb[i];
No :=0;
SetLength(Wkk,No+1);
for i:=0 to Rn-1 do
begin
if Wk[i]<>-1 then
begin
SetLength(Wkk,No+1);
Wkk[No] := WK[i];
Inc(No);
end;
end;
for i:=0 to No-1 do WK[Wkk[i]]:=i+1; for i:=0 to Rn - 1 do WLb[i] := Wk[Wlb[i]]; SetLength(WArea,No+1);
for i:=0 to Rn - 1 do WArea[Wlb[i]] := WArea[Wlb[i]]+(WEx[i]-WSx[i]+1); //标号变色
for i :=0 to Rn - 1 do
begin
if WArea[Wlb[i]]>120 then //大于120的保留,否则置为黑色
begin
for j := WSx[i] to WEx[i] do
begin
m := (Wsy[i]*dwImgWidth+j)*3 ;
lpDestBuf^[m] := 255;
lpDestBuf^[m+1] := 255;
lpDestBuf^[m+2] := 255;
end;
end
else
begin
for j := WSx[i] to WEx[i] do
begin
m := (Wsy[i]*dwImgWidth+j)*3 ;
lpDestBuf^[m] := 0;
lpDestBuf^[m+1] := 0;
lpDestBuf^[m+2] := 0;
end;
end;
end;
SetLength(wBiaoRead,0);
SetLength(Wsy,0);
SetLength(WSx,0);
SetLength(WEx,0);
SetLength(Wlb,0);
SetLength(WArea,0);
SetLength(Wk,0);
SetLength(WKK,0);
end;