OPENCV去除小连通区域,去除孔洞

时间:2025-03-24 07:57:46
  • void RemoveSmallRegion(Mat &Src, Mat &Dst,int AreaLimit, int CheckMode, int NeihborMode)  
  • {  
  •     int RemoveCount = 0;  
  •     //新建一幅标签图像初始化为0像素点,为了记录每个像素点检验状态的标签,0代表未检查,1代表正在检查,2代表检查不合格(需要反转颜色),3代表检查合格或不需检查   
  •     //初始化的图像全部为0,未检查  
  •     Mat PointLabel = Mat::zeros((), CV_8UC1);  
  •     if (CheckMode == 1)//去除小连通区域的白色点  
  •     {  
  •         cout << "去除小连通域.";  
  •         for (int i = 0; i < ; i++)  
  •         {  
  •             for (int j = 0; j < ; j++)  
  •             {  
  •                 if (<uchar>(i, j) < 10)  
  •                 {  
  •                     <uchar>(i, j) = 3;//将背景黑色点标记为合格,像素为3  
  •                 }  
  •             }  
  •         }  
  •     }  
  •     else//去除孔洞,黑色点像素  
  •     {  
  •         cout << "去除孔洞";  
  •         for (int i = 0; i < ; i++)  
  •         {  
  •             for (int j = 0; j < ; j++)  
  •             {  
  •                 if (<uchar>(i, j) > 10)  
  •                 {  
  •                     <uchar>(i, j) = 3;//如果原图是白色区域,标记为合格,像素为3  
  •                 }  
  •             }  
  •         }  
  •     }  
  •   
  •   
  •     vector<Point2i>NeihborPos;//将邻域压进容器  
  •     NeihborPos.push_back(Point2i(-1, 0));  
  •     NeihborPos.push_back(Point2i(1, 0));  
  •     NeihborPos.push_back(Point2i(0, -1));  
  •     NeihborPos.push_back(Point2i(0, 1));  
  •     if (NeihborMode == 1)  
  •     {  
  •         cout << "Neighbor mode: 8邻域." << endl;  
  •         NeihborPos.push_back(Point2i(-1, -1));  
  •         NeihborPos.push_back(Point2i(-1, 1));  
  •         NeihborPos.push_back(Point2i(1, -1));  
  •         NeihborPos.push_back(Point2i(1, 1));  
  •     }  
  •     else cout << "Neighbor mode: 4邻域." << endl;  
  •     int NeihborCount = 4 + 4 * NeihborMode;  
  •     int CurrX = 0, CurrY = 0;  
  •     //开始检测  
  •     for (int i = 0; i < ; i++)  
  •     {  
  •         for (int j = 0; j < ; j++)  
  •         {  
  •             if (<uchar>(i, j) == 0)//标签图像像素点为0,表示还未检查的不合格点  
  •             {   //开始检查  
  •                 vector<Point2i>GrowBuffer;//记录检查像素点的个数  
  •                 GrowBuffer.push_back(Point2i(j, i));  
  •                 <uchar>(i, j) = 1;//标记为正在检查  
  •                 int CheckResult = 0;  
  •   
  •   
  •                 for (int z = 0; z < (); z++)  
  •                 {  
  •                     for (int q = 0; q < NeihborCount; q++)  
  •                     {  
  •                         CurrX = (z).x + (q).x;  
  •                         CurrY = (z).y + (q).y;  
  •                         if (CurrX >= 0 && CurrX<&&CurrY >= 0 && CurrY<)  //防止越界    
  •                         {  
  •                             if (<uchar>(CurrY, CurrX) == 0)  
  •                             {  
  •                                 GrowBuffer.push_back(Point2i(CurrX, CurrY));  //邻域点加入buffer    
  •                                 <uchar>(CurrY, CurrX) = 1;           //更新邻域点的检查标签,避免重复检查    
  •                             }  
  •                         }  
  •                     }  
  •                 }  
  •                 if (()>AreaLimit) //判断结果(是否超出限定的大小),1为未超出,2为超出    
  •                     CheckResult = 2;  
  •                 else  
  •                 {  
  •                     CheckResult = 1;  
  •                     RemoveCount++;//记录有多少区域被去除  
  •                 }  
  •   
  •   
  •                 for (int z = 0; z < (); z++)  
  •                 {  
  •                     CurrX = (z).x;  
  •                     CurrY = (z).y;  
  •                     <uchar>(CurrY,CurrX)+=CheckResult;//标记不合格的像素点,像素值为2  
  •                 }  
  •                 //********结束该点处的检查**********    
  •   
  •   
  •             }  
  •         }  
  •   
  •   
  •     }  
  •   
  •   
  •     CheckMode = 255 * (1 - CheckMode);  
  •     //开始反转面积过小的区域    
  •     for (int i = 0; i < ; ++i)  
  •     {  
  •         for (int j = 0; j < ; ++j)  
  •         {  
  •             if (<uchar>(i,j)==2)  
  •             {  
  •                 <uchar>(i, j) = CheckMode;  
  •             }  
  •             else if (<uchar>(i, j) == 3)  
  •             {  
  •                 <uchar>(i, j) = <uchar>(i, j);  
  •                   
  •             }  
  •         }  
  •     }  
  •     cout << RemoveCount << " objects removed." << endl;  
  • }