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 正则式 概述及常用字符
May 07 Python
Python探索之爬取电商售卖信息代码示例
Oct 27 Python
简单了解Django模板的使用
Dec 20 Python
python保存二维数组到txt文件中的方法
Nov 15 Python
python使用phoenixdb操作hbase的方法示例
Feb 28 Python
python打开使用的方法
Sep 30 Python
使用keras和tensorflow保存为可部署的pb格式
May 25 Python
Windows下Sqlmap环境安装教程详解
Aug 04 Python
Python 代码调试技巧示例代码
Aug 11 Python
Python中基础数据类型 set集合知识点总结
Aug 02 Python
python 使用tkinter与messagebox写界面和弹窗
Mar 20 Python
Python学习之os包使用教程详解
Mar 21 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分页函数
2006/07/08 PHP
PHP连接access数据库
2008/03/27 PHP
php在window iis的莫名问题的测试方法
2013/05/14 PHP
PHP中strnatcmp()函数“自然排序算法”进行字符串比较用法分析(对比strcmp函数)
2016/01/07 PHP
php基于curl重写file_get_contents函数实例
2016/11/08 PHP
Yii框架表单提交验证功能分析
2017/01/07 PHP
PHP中让json_encode不自动转义斜杠“/”的方法
2017/02/28 PHP
PHP常用函数之获取汉字首字母功能示例
2019/10/21 PHP
网站被黑的假象--ARP欺骗之页面中加入一段js
2007/05/16 Javascript
基于JQuery的Select选择框的华丽变身
2011/08/23 Javascript
JavaScript实现16进制颜色值转RGB的方法
2015/02/09 Javascript
2则自己编写的jQuery特效分享
2015/02/26 Javascript
jquery图片切换插件
2015/03/16 Javascript
JavaScript中instanceof运算符的使用示例
2016/06/08 Javascript
JS中使用DOM来控制HTML元素
2016/07/31 Javascript
JS中关于事件处理函数名后面是否带括号的问题
2016/11/16 Javascript
React创建组件的三种方式及其区别
2017/01/12 Javascript
Bootstrap表格制作代码
2017/03/17 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
javascript异步处理与Jquery deferred对象用法总结
2019/06/04 jQuery
在node环境下parse Smarty模板的使用示例代码
2019/11/15 Javascript
vue+element 实现商城主题开发的示例代码
2020/03/26 Javascript
Django原生sql也能使用Paginator分页的示例代码
2017/11/15 Python
浅谈Selenium+Webdriver 常用的元素定位方式
2021/01/13 Python
localstorage和sessionstorage使用记录(推荐)
2017/05/23 HTML / CSS
天巡全球:Skyscanner Global
2017/06/20 全球购物
英国健身超市:Fitness Superstore
2019/06/17 全球购物
JD Sports西班牙:英国领先的运动服装公司
2020/01/06 全球购物
美国基督教约会网站:ChristianCafe.com
2020/02/04 全球购物
俄罗斯最大的香水和化妆品网上商店:Randewoo
2020/11/05 全球购物
师范生实习的个人自我鉴定
2013/10/20 职场文书
上帝也疯狂观后感
2015/06/09 职场文书
公司环境卫生管理制度
2015/08/05 职场文书
中学生打架《检讨书》范文
2019/08/12 职场文书
在Windows下安装配置CPU版的PyTorch的方法
2021/04/02 Python
java高级用法JNA强大的Memory和Pointer
2022/04/19 Java/Android