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

 更新时间:2021年09月06日 08:48:06   作者:翟天保Steven  
本文主要介绍了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-清除小面积连通域内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python创造虚拟环境方法总结

    python创造虚拟环境方法总结

    在本篇内容里我们给大家整理了关于python创造虚拟环境的详细方法和步骤,需要的朋友们学习下。
    2019-03-03
  • Python中的Sequence类型使用实例

    Python中的Sequence类型使用实例

    这篇文章主要为大家介绍了Python中的Sequence类型使用实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • python实现屏保计时器的示例代码

    python实现屏保计时器的示例代码

    这篇文章主要介绍了python实现屏保计时器的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • python递归全排列实现方法

    python递归全排列实现方法

    这篇文章主要为大家详细介绍了python递归全排列实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • Python简单几步画个钻石戒指

    Python简单几步画个钻石戒指

    这篇文章主要介绍了Python简单几步画个钻石戒指,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-09-09
  • Python异步与定时任务提高程序并发性和定时执行效率

    Python异步与定时任务提高程序并发性和定时执行效率

    Python异步与定时任务是Python编程中常用的两种技术,异步任务可用于高效处理I/O密集型任务,提高程序并发性;定时任务可用于定时执行计划任务,提高程序的执行效率。这两种技术的应用有助于提升Python程序的性能和效率
    2023-05-05
  • 在Python下使用Txt2Html实现网页过滤代理的教程

    在Python下使用Txt2Html实现网页过滤代理的教程

    这篇文章主要介绍了在Python下使用Txt2Html实现网页过滤代理的教程,来自IBM官方开发者技术文档,需要的朋友可以参考下
    2015-04-04
  • Python 中的 Counter 模块及使用详解(搞定重复计数)

    Python 中的 Counter 模块及使用详解(搞定重复计数)

    Counter 是一个简单的计数器,用于统计某些可哈希对象的数量。它以字典的形式存储元素和它们的计数,这篇文章主要介绍了Python 中的 Counter 模块及使用详解(搞定重复计数),需要的朋友可以参考下
    2023-04-04
  • Python中的字符串切片(截取字符串)的详解

    Python中的字符串切片(截取字符串)的详解

    这篇文章主要介绍了Python中的字符串切片(截取字符串)的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • python进阶之魔术方法详解

    python进阶之魔术方法详解

    这篇文章主要为大家介绍了python进阶之魔术方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01

最新评论