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求两个list的差集、交集与并集的方法
Nov 01 Python
python实现连接mongodb的方法
May 08 Python
python itchat实现微信自动回复的示例代码
Aug 14 Python
解决在pycharm中显示额外的 figure 窗口问题
Jan 15 Python
Python 堆叠柱状图绘制方法
Jul 29 Python
用python中的matplotlib绘制方程图像代码
Nov 21 Python
Python终端输出彩色字符方法详解
Feb 11 Python
基于pygame实现童年掌机打砖块游戏
Feb 25 Python
对Keras中predict()方法和predict_classes()方法的区别说明
Jun 09 Python
Python调用OpenCV实现图像平滑代码实例
Jun 19 Python
用pushplus+python监控亚马逊到货动态推送微信
Jan 29 Python
Python如何telnet到网络设备
Feb 18 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中实现记住密码自动登录的代码
2011/03/02 PHP
html静态页面调用php文件的方法
2014/11/13 PHP
PHP通过curl获取接口URL的数据方法
2018/05/31 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
2020/03/27 PHP
使javascript也能包含文件
2006/10/26 Javascript
用jquery和json从后台获得数据集的代码
2011/11/07 Javascript
JavaScript中rem布局在react中的应用
2015/12/09 Javascript
jQuery 表单序列化实例代码
2017/06/11 jQuery
node通过npm写一个cli命令行工具
2017/10/12 Javascript
浅谈Node模块系统及其模式
2017/11/17 Javascript
vue.js给动态绑定的radio列表做批量编辑的方法
2018/02/28 Javascript
解决VUEX兼容IE上的报错问题
2018/03/01 Javascript
解决bootstrap-select 动态加载数据不显示的问题
2018/08/10 Javascript
JS实现字符串翻转的方法分析
2018/08/31 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
解决VUE-Router 同一页面第二次进入不刷新的问题
2020/07/22 Javascript
Python使用Django实现博客系统完整版
2020/09/29 Python
Python Tkinter模块实现时钟功能应用示例
2018/07/23 Python
python实现键盘控制鼠标移动
2020/11/27 Python
python基于TCP实现的文件下载器功能案例
2019/12/10 Python
python同义词替换的实现(jieba分词)
2020/01/21 Python
pandas实现excel中的数据透视表和Vlookup函数功能代码
2020/02/14 Python
Python在线和离线安装第三方库的方法
2020/10/31 Python
欧洲最大的化妆品连锁公司:Douglas道格拉斯
2017/05/06 全球购物
全球销量第一生发产品:Viviscal
2017/12/21 全球购物
利物浦足球俱乐部官方网上商店:Liverpool FC Official Store
2018/01/13 全球购物
Public Desire美国/加拿大:全球性的在线鞋类品牌
2018/12/17 全球购物
关于幼儿的自我评价
2013/12/18 职场文书
学子宴答谢词
2014/01/25 职场文书
个人简历自我评价范文
2014/02/04 职场文书
艺校音乐专业自我鉴定范文
2014/03/01 职场文书
班组建设经验交流材料
2014/05/12 职场文书
2016教师党员学习心得体会
2016/01/21 职场文书
用Python将GIF动图分解成多张静态图片
2021/06/11 Python
Python 可迭代对象 iterable的具体使用
2021/08/07 Python
python的html标准库
2022/04/29 Python