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通过websocket与js客户端通信示例分析
Jun 25 Python
Python字符串处理之count()方法的使用
May 18 Python
Python实现截屏的函数
Jul 25 Python
Python 列表排序方法reverse、sort、sorted详解
Jan 22 Python
Python实现钉钉发送报警消息的方法
Feb 20 Python
Python实现EXCEL表格的排序功能示例
Jun 25 Python
Python实现图片批量加入水印代码实例
Nov 30 Python
Django values()和value_list()的使用
Mar 31 Python
Python常用模块函数代码汇总解析
Aug 31 Python
如何用Django处理gzip数据流
Jan 29 Python
python数据库批量插入数据的实现(executemany的使用)
Apr 30 Python
python如何将mat文件转为png
Jul 15 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/01/14 PHP
JS中encodeURIComponent函数用php解码的代码
2012/03/01 PHP
php 模拟 asp.net webFrom 按钮提交事件实例
2014/10/13 PHP
php自定义apk安装包实例
2014/10/20 PHP
100多行PHP代码实现socks5代理服务器[2]
2016/05/05 PHP
Yii2简单实现给表单添加验证码的方法
2016/07/18 PHP
Linux下快速搭建php开发环境
2017/03/13 PHP
JavaScript asp.net 获取当前超链接中的文本
2009/04/14 Javascript
JS实现商品倒计时实现代码
2013/05/03 Javascript
javascript数组操作(创建、元素删除、数组的拷贝)
2014/04/07 Javascript
javascript比较两个日期相差天数的方法
2015/07/23 Javascript
深入浅析Bootstrap列表组组件
2016/05/03 Javascript
easyui combobox开启搜索自动完成功能的实例代码
2016/11/08 Javascript
JS实现焦点图轮播效果的方法详解
2016/12/19 Javascript
Vue自定义图片懒加载指令v-lazyload详解
2020/12/31 Javascript
AngularJS 限定$scope的范围实例详解
2017/06/23 Javascript
vue中本地静态图片路径写法
2018/03/06 Javascript
8 个有用的JS技巧(推荐)
2019/07/03 Javascript
Element-ui树形控件el-tree自定义增删改和局部刷新及懒加载操作
2020/08/31 Javascript
Python基础之函数用法实例详解
2014/09/10 Python
Window10+Python3.5安装opencv的教程推荐
2018/04/02 Python
python中找出numpy array数组的最值及其索引方法
2018/04/17 Python
pygame游戏之旅 载入小车图片、更新窗口
2018/11/20 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
2019/04/11 Python
Python原始套接字编程实例解析
2020/01/29 Python
Python图像识别+KNN求解数独的实现
2020/11/13 Python
用python制作个音乐下载器
2021/01/30 Python
selenium+python自动化78-autoit参数化与批量上传功能的实现
2021/03/04 Python
教师节活动主持词
2014/04/02 职场文书
学校交通安全责任书
2014/08/25 职场文书
作风建设年活动总结
2014/08/27 职场文书
群众路线教育实践活动学习笔记内容
2014/11/06 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
2016年小学党支部创先争优活动总结
2016/04/05 职场文书
2019优秀干部竞聘演讲稿范文!
2019/07/02 职场文书
Spring Boot 的创建和运行示例代码详解
2022/07/23 Java/Android