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检测主机存活端口及检查存活主机
Oct 12 Python
浅谈python正则的常用方法 覆盖范围70%以上
Mar 14 Python
python os用法总结
Jun 08 Python
python用opencv批量截取图像指定区域的方法
Jan 24 Python
Python实现定时自动关闭的tkinter窗口方法
Feb 16 Python
pygame实现非图片按钮效果
Oct 29 Python
Python数据可视化处理库PyEcharts柱状图,饼图,线性图,词云图常用实例详解
Feb 10 Python
基于Django signals 信号作用及用法详解
Mar 28 Python
Django 用户登陆访问限制实例 @login_required
May 13 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
May 18 Python
Django使用django-simple-captcha做验证码的实现示例
Jan 07 Python
Python3.9.0 a1安装pygame出错解决全过程(小结)
Feb 02 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
php与Mysql的一些简单的操作
2015/02/26 PHP
微信公众号实现会员卡领取功能
2017/06/08 PHP
PHP开发之归档格式phar文件概念与用法详解【创建,使用,解包还原提取】
2017/11/17 PHP
php中的钩子理解及应用实例分析
2019/08/30 PHP
cookie丢失问题(认证失效) Authentication (用户验证信息)也会丢失
2009/06/04 Javascript
jquery插件珍藏(图片局部放大/信息提示框)
2013/01/08 Javascript
网站404页面3秒后跳到首页的实例代码
2013/08/16 Javascript
javascript删除option选项的多种方法总结
2013/11/22 Javascript
javascript如何动态加载表格与动态添加表格行
2013/11/27 Javascript
深入理解javascript中return的作用
2013/12/30 Javascript
node.js中的fs.truncate方法使用说明
2014/12/15 Javascript
jQuery插件expander实现图片翻转特效
2015/05/21 Javascript
探究Javascript模板引擎mustache.js使用方法
2016/01/26 Javascript
详解vuex 中的 state 在组件中如何监听
2017/05/23 Javascript
详解vue-router 路由元信息
2017/09/13 Javascript
JS设计模式之单例模式(一)
2017/09/29 Javascript
JavaScript同源策略和跨域访问实例详解
2018/04/03 Javascript
vue.js打包之后可能会遇到的坑!
2018/06/03 Javascript
vue-cli脚手架的安装教程图解
2018/09/02 Javascript
小程序组件之仿微信通讯录的实现代码
2018/09/12 Javascript
微信小程序 扭蛋抽奖机css3动画实现详解
2019/07/19 Javascript
layui按条件隐藏表格列的实例
2019/09/19 Javascript
async/await让异步操作同步执行的方法详解
2019/11/01 Javascript
Python求两个list的差集、交集与并集的方法
2014/11/01 Python
Python中List.index()方法的使用教程
2015/05/20 Python
CentOS中升级Python版本的方法详解
2017/07/10 Python
PyCharm+PySpark远程调试的环境配置的方法
2018/11/29 Python
Python单元测试unittest的具体使用示例
2018/12/17 Python
Python基本socket通信控制操作示例
2019/01/30 Python
python 通过可变参数计算n个数的乘积方法
2019/06/13 Python
python 日志 logging模块详细解析
2020/03/31 Python
Python使用Chrome插件实现爬虫过程图解
2020/06/09 Python
HTML5 history新特性pushState、replaceState及两者的区别
2015/12/26 HTML / CSS
人力资源专员岗位职责
2014/01/30 职场文书
晚会主持人开场白台词
2015/05/28 职场文书
《最后一头战象》教学反思
2016/02/16 职场文书