• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    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::vectorstd::vectorcv::Point> > contours;  // 创建轮廓容器
    	std::vectorcv::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::vectorstd::vectorcv::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.ptruchar>(i);
    					for (int j = rect.x; j  rect.x + rect.width; j++) 
    					{
    						// 将连通区的值置0
    						if (output_data[j] == 255) 
    						{
    							output_data[j] = 0;
    						}
    					}
    				}
    			}
    			itc++;
    		}
    	}
    }

    测试代码

    #includeiostream>
    #includeopencv2/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::vectorstd::vectorcv::Point> > contours;  // 创建轮廓容器
    	std::vectorcv::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::vectorstd::vectorcv::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.ptruchar>(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-清除小面积连通域内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • OpenCV实现图像连通域
    • 使用OpenCV去除面积较小的连通域
    • 使用OpenCV获取图片连通域数量,并用不同颜色标记函
    上一篇:python copy模块中的函数实例用法
    下一篇:OpenCV实现背景分离(证件照背景替换)
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    OpenCV清除小面积连通域的实现方法 OpenCV,清除,小,面积,连通,