二值形态学——腐蚀与膨胀 及 C语言代码实现
参考文献:数字图像处理(第三版) 何东健 西安电子科技大学出版社
二值形态学中的运算对象是集合, 但实际运算中, 当涉及两个集合时并不把它们看作是互相对等的。 一般设A为图像集合, S为结构元素, 数学形态学运算是用S对A进行操作。 结构元素本身也是一个图像集合, 不过通常其尺寸要比目标图像小得多。 对结构元素可指定一个原点, 将其作为结构元素参与形态学运算的参考点。 原点可包含在结构元素中, 也可不包含在结构元素中, 但运算的结果常不相同。 以下用黑点代表值为1的区域, 白点代表值为0的区域, 运算对于值为1的区域进行。
1.腐蚀
腐蚀是一种最基本的数学形态学运算。 对给定的目标图像X和结构元素S, 将S在图像上移动, 则在每一个当前位置x, S+x只有3种可能的状态, 如下图所示:
第(1)种情形说明S+x与X相关;
第(2)种情形说明S+x与X不相关;
第(3)种情形说明S+x与X只是部分相关。
因而满足(1)式的点x的全体元素,称该点集为S对X的腐蚀(简称腐蚀, 也称X用S腐蚀),记为。
腐蚀也可以用集合的方式定义:
该式表明, X用S腐蚀的结果是所有使S平移x后仍在X中的x的集合。 换句话说, 用S来腐蚀X得到的集合是S完全包含在X中时S的原点位置的集合。
腐蚀在数学形态学运算中的作用是消除物体边界点、 去除小于结构元素的物体、 清除两个物体间的细小连通等。 如果结构元素取3×3的像素块, 腐蚀将使物体的边界沿周边减少1个像素。
“腐蚀”图解:(腐蚀将图像(区域)缩小了)
代码实现:
【注】二值腐蚀基本运算,背景为黑色,目标为白色。
//二值腐蚀
/*函数参数:
a——待腐蚀的图像
b——腐蚀后的结果
mat[5][5]——结构元素,我这里默认设了5*5的大小
*/
void Bi_Corrosion(Mat &a, Mat &b, int mat[][])
{
int i, j, k, o;
int rows = a.rows;
int cols = a.cols*a.channels(); bool flag; uchar *dst = b.data;
uchar *src = a.data;
//针对图像中每一个像素位置,判断是否结构元素能填入目标内部
for(i = ; i < rows-; i++) {
for(j = ; j < cols-; j++) {
//判断结构元素是否可以在当前点填入目标内部,1为可以,0为不可以
flag = ;
for(k = -; k <= && flag; k++) {
for(o = -; o <= ; o++) {
//如果当前结构元素位置为1,判断与对应图像上的像素点是否为非0
if(mat[k+][o+]) {
//如果图像当前像素为0,则没有击中该点,不是腐蚀的输出
if(!*(src+(i+k)*cols+j+o)){
flag = ; break;
}
}
}
}
*(dst+i*cols+j) = flag ? : ;
}
}
}
2.膨胀
腐蚀可以看作是将图像X中每一个与结构元素S全等的子集S+x收缩为点x。 反之, 也可以将X中的每一个点x扩大为S+x, 即膨胀运算, 记为。用集合语言定义膨胀运算的定义形式为:
图示:
【注意】来看下特殊情况: 用B膨胀后,结果向左平移了;而用B图像的反射膨胀后位置不变。
对于非对称结构S,膨胀后会使得原图错移,但膨胀不会,总的位置和形状不变,因此膨胀公式也可以写做:
对集合X的膨胀也可以看做是对集合X补集的腐蚀的补集具有对偶特性:
腐蚀和膨胀运算与集合运算的关系如下:
代码实现:
【注】二值膨胀基本运算,背景为黑色,目标为白色。
//二值膨胀
/*函数参数:
a——待腐蚀的图像
b——腐蚀后的结果
mat——结构元素
*/
void Bi_Expansion(Mat &a, Mat &b, int mat[][]) {
int i, j, k, o;
int rows = a.rows;
int cols = a.cols*a.channels();
Mat tmp = a.clone();
uchar* src = tmp.data;
//膨胀是对图像中目标补集的腐蚀,因此先求输入图像数据的补集
for(i = ; i < rows; i++)
for(j = ; j < cols; j++)
*(src+i*cols+j) = - *(src+i*cols+j);
//膨胀是结构元素的对称集对补集的腐蚀,此处求其反射
for(i = ; i < ; i++)
for(j = ; j <= i; j++)
mat[i][j] = mat[j][i];
bool flag;
uchar* dst = b.data;
//针对图像中每一个像素位置,判断是否结构元素能填入目标内部
for(i = ; i < rows-; i++) {
for(j = ; j < cols-; j++) {
//判断结构元素是否可以在当前点填入目标内部,1为可以,0为不可以
flag = ;
for(k = -; k <= && flag; k++) {
for(o = -; o <= ; o++) {
//如果当前结构元素位置为1,判断与对应图像上的像素点是否为非0
if(mat[k+][o+]) {
if(!*(src+(i+k)*cols+j+o)){//没击中
flag = ; break;
}
}
}
}
*(dst+i*cols+j) = flag ? : ;
}
}
//用结构元素对称集对目标补集腐蚀后,还要对结构再求一次补集,才是膨胀结构输出
//赋值结构元素腐蚀漏掉的区域,使原图像恢复为二值图像
for(i = ; i < rows; i++) {
for(j = ; j < cols; j++) {
*(dst+i*cols+j) = - *(dst+i*cols+j);
if(*(dst+i*cols+j) != && *(dst+i*cols+j) != )
*(dst+i*cols+j) = ;
}
}
}
二值形态学——腐蚀与膨胀 及 C语言代码实现的更多相关文章
- OpenCV学习 7:图像形态学:腐蚀、膨胀
原创文章,欢迎转载,转载请注明出处 首先什么是图像形态学?额,这个抄下百度到的答案.基本思想: 用具有一定形态的结构元素去度量和提取图像中的对应形状已达到对图像分析和识别的目的,形态学图像处理表 ...
- opencv中的图像形态学——腐蚀膨胀
腐蚀膨胀是图像形态学比较常见的处理,腐蚀一般可以用来消除噪点,分割出独立的图像元素等. 一般腐蚀操作对二值图进行处理,腐蚀操作如下图,中心位置的像素点是否与周围领域的像素点颜色一样(即是否是白色点,即 ...
- OpenCV学习笔记(六) 滤波器 形态学操作(腐蚀、膨胀等)
转自:OpenCV 教程 另附:计算机视觉:算法与应用(2012),Learning OpenCV(2009) 平滑图像:滤波器 平滑 也称 模糊, 是一项简单且使用频率很高的图像处理方法.平滑处理的 ...
- 机器学习进阶-项目实战-信用卡数字识别 1.cv2.findContour(找出轮廓) 2.cv2.boudingRect(轮廓外接矩阵位置) 3.cv2.threshold(图片二值化操作) 4.cv2.MORPH_TOPHAT(礼帽运算突出线条) 5.cv2.MORPH_CLOSE(闭运算图片内部膨胀) 6. cv2.resize(改变图像大小) 7.cv2.putText(在图片上放上文本)
7. cv2.putText(img, text, loc, text_font, font_scale, color, linestick) # 参数说明:img表示输入图片,text表示需要填写的 ...
- opencv 4 图像处理(2 形态学滤波:腐蚀与膨胀,开运算、闭运算、形态学梯度、顶帽、黑帽)
腐蚀与膨胀 膨胀(求局部最大值)(dilate函数) #include <opencv2/core/core.hpp> #include <opencv2/highgui/highg ...
- c#数字图像处理(十二)图像的腐蚀与膨胀
背景知识 腐蚀与膨胀基本原理:就是用一个特定的结构元素来与待处理图像按像素做逻辑操作:可以理解成拿一个带孔的网格板(结构元素矩阵中元素为1的为孔)盖住图像的某一部分,然后按照各种不同的观察方式来确定操 ...
- 【python-opencv】17-形态学操作-腐蚀与膨胀
形态学操作其实就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖",看下图就明白了: 形态学操作一般作用于二值化图(也可直接作用于原图),来连接相邻的元素 ...
- OpenCV腐蚀与膨胀(Eroding and Dilating)
腐蚀与膨胀(Eroding and Dilating) 目标 本文档尝试解答如下问题: 如何使用OpenCV提供的两种最基本的形态学操作,腐蚀与膨胀( Erosion 与 Dilation): ero ...
- ComicEnhancerPro 系列教程十七:二值化图像去毛刺
作者:马健邮箱:stronghorse_mj@hotmail.com 主页:http://www.comicer.com/stronghorse/ 发布:2017.07.23 教程十七:二值化图像去毛 ...
随机推荐
- 转:详解PV、UV、VV、IP及其关系与计算
一.什么是PV? PV即Page View,网站浏览量,指页面浏览的次数,用以衡量网站用户访问的网页数量.用户每次打开一个页面便记录1次PV,多次打开同一页面则浏览量累计.一般来说,PV与来访者的数量 ...
- EF Code-First数据迁移
Code-First数据迁移 首先要通过NuGet将EF升级至最新版本. 新建MVC 4项目MvcMigrationDemo 添加数据模型 Person 和 Department,定义如下: usi ...
- [javaSE] 数据结构(队列)
队列是一种线性存储结构,他有以下特点: 1.队列中数据是按照“先进先出”方式进出队列的 2.队列只允许在“队首”进行删除操作,在“队尾”进行插入操作 3.队列通常包含两种操作:入队列和出队列 使用数组 ...
- 十四、curator recipes之DistributedAtomicLong
简介 和Java的AtomicLong没有太大的不同DistributedAtomicLong旨在分布式场景中维护一个Long类型的数据,你可以像普通单机环境一样来使用它. 官方文档:http://c ...
- K:求取两个数的最大公约数的两个算法
相关介绍: 最大公因数,也称最大公约数.最大公因子,指两个或多个整数共有约数中最大的一个.a,b的最大公约数记为gcd(a,b).同样的,a,b,c的最大公约数记为gcd(a,b,c),多个整数的最 ...
- MVC 导出Execl 的总结几种方式 (一)
在ASP.NET 中导出Execl 表格有很多方式,有利有弊,就是看自己怎么使用了:下面就是自己总结了几种导出Execl 方式的,仅供参考. 导出Execl 的原理都是一样的,其实都是将数据整合成ta ...
- SQL Server Metadata
http://www.devart.com/dotconnect/sqlserver/docs/MetaData.htmlhttps://msdn.microsoft.com/en-us/librar ...
- Luogu 4240:毒瘤之神的考验
传送门 Sol 分开考虑 \(\varphi(ij)\) 中 \(ij\) 的质因子 那么 \[\varphi(ij)=\frac{\varphi(i)\varphi(j)gcd(i,j)}{\var ...
- js 对象数组去重
var arr = [{ "name": "ZYTX", "age": "Y13xG_4wQnOWK1QwJLgg11d0pS4h ...
- Canvas中的剪切clip()方法
Canvas中的剪切 接下来我们要聊的不是图像的合成,而是Canvas中的另一个有用的功能:剪切区域.它是Canvas之中由路径所定义的一块区域,浏览器会将所有的绘图操作都限制在本区域内执行.在默认情 ...