圆形和三角形都是封闭图形,且大小差别较大。

解决方案 »

  1.   

    如果你说他们的大小差别较大那就很好解决,你可以看看《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;