您当前的位置:首页 > IT编程 > python
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch | 异常检测 | Transformers | 情感分类 | 知识图谱 |

自学教程:OpenCV清除小面积连通域的实现方法

51自学网 2021-10-30 22:13:56
  python
这篇教程OpenCV清除小面积连通域的实现方法写得很实用,希望能帮到您。

场景需求

       使用OpenCV,往往遇到这类场景:需要清除目标图像中比较小的噪声区,保留主要区域信息。

       特此分享自己写的一个简单的清除小面积连通域函数,逻辑比较简单,给大家留出了足够的发展空间,根据自身场景需求进行调整。

       原理可以简单归结为:搜索图像的连通区轮廓->遍历各个连通区->基于阈值删除面积较小的连通区

       运行速度方面,我没单独测试过这个单元,大家如果试过之后太慢可以评论告诉我哦~

       反正平常我工作跑那种2000*2000的图像,这个函数的耗时几乎忽略不计。。。

C++实现代码

/*** @brief  Clear_MicroConnected_Areas         清除微小面积连通区函数* @param  src                                输入图像矩阵* @param  dst                                输出结果* @return min_area                           设定的最小面积清除阈值*/void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area){	// 备份复制	dst = src.clone();	std::vector<std::vector<cv::Point> > contours;  // 创建轮廓容器	std::vector<cv::Vec4i> 	hierarchy;   	// 寻找轮廓的函数	// 第四个参数CV_RETR_EXTERNAL,表示寻找最外围轮廓	// 第五个参数CV_CHAIN_APPROX_NONE,表示保存物体边界上所有连续的轮廓点到contours向量内	cv::findContours(src, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point()); 	if (!contours.empty() && !hierarchy.empty()) 	{		std::vector<std::vector<cv::Point> >::const_iterator itc = contours.begin();		// 遍历所有轮廓		while (itc != contours.end()) 		{			// 定位当前轮廓所在位置			cv::Rect rect = cv::boundingRect(cv::Mat(*itc));			// contourArea函数计算连通区面积			double area = contourArea(*itc);			// 若面积小于设置的阈值			if (area < min_area) 			{				// 遍历轮廓所在位置所有像素点				for (int i = rect.y; i < rect.y + rect.height; i++) 				{					uchar *output_data = dst.ptr<uchar>(i);					for (int j = rect.x; j < rect.x + rect.width; j++) 					{						// 将连通区的值置0						if (output_data[j] == 255) 						{							output_data[j] = 0;						}					}				}			}			itc++;		}	}}

测试代码

#include<iostream>#include<opencv2/opencv.hpp> using namespace std;using namespace cv; void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area); int main(void){	Mat A = Mat::zeros(500, 500, CV_8UC1);	circle(A, Point2i(100, 100), 50, 255, -1);	circle(A, Point2i(300, 400), 15, 255, -1);	Mat B;	Clear_MicroConnected_Areas(A, B, 1000); 	imshow("before:A", A);	imshow("after:B", B);	waitKey(0); 	system("pause");	return 0;} void Clear_MicroConnected_Areas(cv::Mat src, cv::Mat &dst, double min_area){	// 备份复制	dst = src.clone();	std::vector<std::vector<cv::Point> > contours;  // 创建轮廓容器	std::vector<cv::Vec4i> 	hierarchy;   	// 寻找轮廓的函数	// 第四个参数CV_RETR_EXTERNAL,表示寻找最外围轮廓	// 第五个参数CV_CHAIN_APPROX_NONE,表示保存物体边界上所有连续的轮廓点到contours向量内	cv::findContours(src, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE, cv::Point()); 	if (!contours.empty() && !hierarchy.empty()) 	{		std::vector<std::vector<cv::Point> >::const_iterator itc = contours.begin();		// 遍历所有轮廓		while (itc != contours.end()) 		{			// 定位当前轮廓所在位置			cv::Rect rect = cv::boundingRect(cv::Mat(*itc));			// contourArea函数计算连通区面积			double area = contourArea(*itc);			// 若面积小于设置的阈值			if (area < min_area) 			{				// 遍历轮廓所在位置所有像素点				for (int i = rect.y; i < rect.y + rect.height; i++) 				{					uchar *output_data = dst.ptr<uchar>(i);					for (int j = rect.x; j < rect.x + rect.width; j++) 					{						// 将连通区的值置0						if (output_data[j] == 255) 						{							output_data[j] = 0;						}					}				}			}			itc++;		}	}}

测试效果

 

图1 处理前后图

到此这篇关于OpenCV-清除小面积连通域的文章就介绍到这了,更多相关OpenCV-清除小面积连通域内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net!


python copy模块中的函数实例用法
OpenCV实现背景分离(证件照背景替换)
万事OK自学网:51自学网_软件自学网_CAD自学网自学excel、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。