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描述器descriptor详解
Feb 03 Python
python类继承与子类实例初始化用法分析
Apr 17 Python
Python序列化基础知识(json/pickle)
Oct 19 Python
使用 Python 实现微信公众号粉丝迁移流程
Jan 03 Python
Python的条件表达式和lambda表达式实例
Jan 31 Python
Pandas之排序函数sort_values()的实现
Jul 09 Python
python实现批量处理将图片粘贴到另一张图片上并保存
Dec 12 Python
python常用运维脚本实例小结
Feb 14 Python
在pytorch中动态调整优化器的学习率方式
Jun 24 Python
python高级特性简介
Aug 13 Python
python获取淘宝服务器时间的代码示例
Apr 22 Python
Python极值整数的边界探讨分析
Sep 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中ob(Output Buffer 输出缓冲)函数使用方法
2007/07/21 PHP
PHP代码优化的53个细节
2014/03/03 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
PHP getallheaders无法获取自定义头(headers)的问题
2016/03/23 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
PHP 判断字符串是中文还是英文, 或者是中英混合
2021/03/09 PHP
JSON.parse 解析字符串出错的解决方法
2010/07/08 Javascript
Jquery优化效率 提升性能解决方案
2010/09/06 Javascript
JavaScript将数据转换成整数的方法
2014/01/04 Javascript
javascript修改IMG标签的src问题
2014/03/28 Javascript
在Node.js中实现文件复制的方法和实例
2014/06/05 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
JS+CSS3实现超炫的散列画廊特效
2016/07/16 Javascript
Vue.js每天必学之过滤器与自定义过滤器
2016/09/07 Javascript
Jquery 整理元素选取、常用方法一览表
2016/11/26 Javascript
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法
2018/01/25 Javascript
js数组中去除重复值的几种方法
2020/08/03 Javascript
对python3 中方法各种参数和返回值详解
2018/12/15 Python
pandas 数据索引与选取的实现方法
2019/06/21 Python
Python交互式图形编程的实现
2019/07/25 Python
Django 后台获取文件列表 InMemoryUploadedFile的例子
2019/08/07 Python
Python Web框架之Django框架cookie和session用法分析
2019/08/16 Python
Python使用QQ邮箱发送邮件报错smtplib.SMTPAuthenticationError
2019/12/20 Python
Python递归调用实现数字累加的代码
2020/02/25 Python
西班牙著名的珠宝首饰品牌:P D PAOLA
2018/09/15 全球购物
俄罗斯三星品牌商店:GalaxyStore
2020/11/04 全球购物
山海经纬软件测试笔试题和面试题
2013/04/02 面试题
公开承诺书格式
2014/05/21 职场文书
客户答谢会活动方案
2014/08/31 职场文书
县政府领导班子四风问题对照检查材料思想汇报
2014/09/26 职场文书
2014年高数考试作弊检讨书
2014/12/14 职场文书
《雪地里的小画家》教学反思
2016/02/16 职场文书
元素水平垂直居中的方式
2021/03/31 HTML / CSS
vue代码分块和懒加载非必要资源文件
2022/04/11 Vue.js