EN
http://cdn.baiduyun.im/video/54465946.html

[C#]使用Opencvsharp去除面积较小的连通域

2025-06-24 11:49:52 来源: 新华社
字号:默认超大|打印|

【C++介绍】。

opencv实现有更好的算法,您可以参考本博客OpenCV去除面积较小的连通域_c#opencv 筛选小区域-CSDN博客。

但是opencvsharp没有对应的同类算法󿀌为了照顾C#编程学生,因此将 将面积较小的连通域算法删除为C#代码。

方法一流程:

//=======函数实现=====================================================================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(Src.size(), CV_8UC1);	if (CheckMode == 1)///去除小连通区域的白点  	{ 		//cout << "去除小连通域.";		for (int i = 0; i < Src.rows; i++)		{ 			for (int j = 0; j < Src.cols; j++)			{ 				if (Src.at<uchar>(i, j) < 10)				{ 					PointLabel.at<uchar>(i, j) = 3;///标记背景黑点合格,像素为3  				}			}		}	}	else//去除孔洞󿼌黑色点像素  	{ 		//cout << "除孔";		for (int i = 0; i < Src.rows; i++)		{ 			for (int j = 0; j < Src.cols; j++)			{ 				if (Src.at<uchar>(i, j) > 10)				{ 					PointLabel.at<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 int a = 0;//cout << "Neighbor mode: 4邻域." << endl;	int NeihborCount = 4 + 4 * NeihborMode;	int CurrX = 0, CurrY = 0;	//开始检测  	for (int i = 0; i < Src.rows; i++)	{ 		for (int j = 0; j < Src.cols; j++)		{ 			if (PointLabel.at<uchar>(i, j) == 0)//标签图像素点0,表示未检查的不合格点尚未检查  			{    //开始检查  				vector<Point2i>GrowBuffer;///记录检查像素点的数量  				GrowBuffer.push_back(Point2i(j, i));				PointLabel.at<uchar>(i, j) = 1;///标记正在检查中  				int CheckResult = 0;				for (int z = 0; z < GrowBuffer.size(); z++)				{ 					for (int q = 0; q < NeihborCount; q++)					{ 						CurrX = GrowBuffer.at(z).x + NeihborPos.at(q).x;						CurrY = GrowBuffer.at(z).y + NeihborPos.at(q).y;						if (CurrX >= 0 && CurrX<Src.cols&&CurrY >= 0 && CurrY<Src.rows)  ///防止越界    						{ 							if (PointLabel.at<uchar>(CurrY, CurrX) == 0)							{ 								GrowBuffer.push_back(Point2i(CurrX, CurrY));  //在邻域点添加buffer    								PointLabel.at<uchar>(CurrY, CurrX) = 1;           ///更新邻域点的检查标签,避免重复检查    							}						}					}				}				if (GrowBuffer.size()>AreaLimit) ///判断结果(是否超过限定大小),11不超过,2为超出    					CheckResult = 2;				else				{ 					CheckResult = 1;					RemoveCount++;//记录有多少区域被删除  				}				for (int z = 0; z < GrowBuffer.size(); z++)				{ 					CurrX = GrowBuffer.at(z).x;					CurrY = GrowBuffer.at(z).y;					PointLabel.at<uchar>(CurrY, CurrX) += CheckResult;//标记不合格的像素点,像素值为2  				}				//。

【我要纠错】责任编辑:新华社