OPENCV去除小连通区域,去除孔洞的实例讲解


Posted in Python onJune 21, 2018

一、对于二值图,0代表黑色,255代表白色。去除小连通区域与孔洞,小连通区域用8邻域,孔洞用4邻域。

OPENCV去除小连通区域,去除孔洞的实例讲解

函数名字为:void RemoveSmallRegion(Mat &Src, Mat &Dst,int AreaLimit, int CheckMode, int NeihborMode)

CheckMode: 0代表去除黑区域,1代表去除白区域; NeihborMode:0代表4邻域,1代表8邻域;

如果去除小连通区域CheckMode=1,NeihborMode=1去除孔洞CheckMode=0,NeihborMode=0

记录每个像素点检验状态的标签,0代表未检查,1代表正在检查,2代表检查不合格(需要反转颜色),3代表检查合格或不需检查 。

1.先对整个图像扫描,如果是去除小连通区域,则将黑色的背景图作为合格,像素值标记为3,如果是去除孔洞,则将白色的色素点作为合格,像素值标记为3。

2.扫面整个图像,对图像进行处理。

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 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) //判断结果(是否超出限定的大小),1为未超出,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
				}
				//********结束该点处的检查********** 


			}
		}


	}


	CheckMode = 255 * (1 - CheckMode);
	//开始反转面积过小的区域 
	for (int i = 0; i < Src.rows; ++i)
	{
		for (int j = 0; j < Src.cols; ++j)
		{
			if (PointLabel.at<uchar>(i,j)==2)
			{
				Dst.at<uchar>(i, j) = CheckMode;
			}
			else if (PointLabel.at<uchar>(i, j) == 3)
			{
				Dst.at<uchar>(i, j) = Src.at<uchar>(i, j);
				
			}
		}
	}
	cout << RemoveCount << " objects removed." << endl;
}

调用函数:dst是原来的二值图。

Mat erzhi1 = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC1);
RemoveSmallRegion(dst, erzhi,100, 1, 1);
RemoveSmallRegion(erzhi, erzhi,100, 0, 0);
imshow("erzhi1", erzhi);

OPENCV去除小连通区域,去除孔洞的实例讲解

和之前的图像相比

OPENCV去除小连通区域,去除孔洞的实例讲解

以上这篇OPENCV去除小连通区域,去除孔洞的实例讲解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用python实现baidu hi自动登录的代码
Feb 10 Python
Python入门篇之对象类型
Oct 17 Python
Python网页解析利器BeautifulSoup安装使用介绍
Mar 17 Python
使用Python的Tornado框架实现一个Web端图书展示页面
Jul 11 Python
浅谈Python浅拷贝、深拷贝及引用机制
Dec 15 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
Apr 27 Python
IntelliJ IDEA安装运行python插件方法
Dec 10 Python
Django框架模板介绍
Jan 15 Python
Python基于requests库爬取网站信息
Mar 02 Python
浅谈多卡服务器下隐藏部分 GPU 和 TensorFlow 的显存使用设置
Jun 30 Python
pytorch下的unsqueeze和squeeze的用法说明
Feb 06 Python
Python代码实现双链表
May 25 Python
python读取文本绘制动态速度曲线
Jun 21 #Python
python实现可视化动态CPU性能监控
Jun 21 #Python
python实时监控cpu小工具
Jun 21 #Python
python实现监控某个服务 服务崩溃即发送邮件报告
Jun 21 #Python
python实现简易内存监控
Jun 21 #Python
Python实现的微信好友数据分析功能示例
Jun 21 #Python
python skimage 连通性区域检测方法
Jun 21 #Python
You might like
打造计数器DIY三步曲(下)
2006/10/09 PHP
PHP实现自动对图片进行滚动显示的方法
2015/03/12 PHP
PHP使用DirectoryIterator显示下拉文件列表的方法
2015/03/13 PHP
PHP生成随机密码4种方法及性能对比
2020/12/11 PHP
jQuery插件Skippr实现焦点图幻灯片特效
2015/04/12 Javascript
JavaScript动态数量的文件上传控件
2016/11/18 Javascript
html判断当前页面是否在iframe中的实例
2016/11/30 Javascript
js仿搜狐视频记录片列表展示效果
2020/05/30 Javascript
jquery实现tab键进行选择后enter键触发click行为
2017/03/29 jQuery
关于vue中 $emit的用法详解
2018/04/12 Javascript
微信小程序实现默认第一个选中变色效果
2018/07/17 Javascript
jQuery实现获取及设置CSS样式操作详解
2018/09/05 jQuery
微信运维交互机器人的示例代码
2018/11/12 Javascript
微信小程序开发实现的IP地址查询功能示例
2019/03/28 Javascript
微信小程序tabBar 返回tabBar不刷新页面
2019/07/25 Javascript
angularjs自定义过滤器demo示例
2019/08/24 Javascript
Vue组件间数据传递的方式(3种)
2020/07/13 Javascript
详解微信小程序(Taro)手动埋点和自动埋点的实现
2021/03/02 Javascript
Python的ORM框架SQLObject入门实例
2014/04/28 Python
python中base64加密解密方法实例分析
2015/05/16 Python
python 对象和json互相转换方法
2018/03/22 Python
对Python 网络设备巡检脚本的实例讲解
2018/04/22 Python
浅析Python+OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估
2019/10/17 Python
详解使用HTML5 Canvas创建动态粒子网格动画
2016/12/14 HTML / CSS
印度婴儿用品在线商店:Firstcry.com
2016/12/05 全球购物
什么是TCP/IP
2014/07/27 面试题
工程现场管理求职自荐信
2013/10/02 职场文书
班主任经验交流会主持词
2014/04/01 职场文书
经管应届生求职信范文
2014/05/18 职场文书
观看信仰心得体会
2014/09/04 职场文书
安全守法证明
2015/06/23 职场文书
初级职称评定工作总结
2015/08/13 职场文书
你对自己的信用报告有过了解吗?
2019/07/09 职场文书
个人销售励志奋斗口号
2019/12/05 职场文书
用Python提取PDF表格的方法
2021/04/11 Python
Python 多线程之threading 模块的使用
2021/04/14 Python