形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑

2023-12-26 04:48

本文主要是介绍形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



本系列文章由@浅墨_毛星云 出品,转载请注明出处。  

文章链接: http://blog.csdn.net/poem_qianmo/article/details/23184547

作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442

知乎:http://www.zhihu.com/people/mao-xing-yun

邮箱: happylifemxy@163.com

写作当前博文时配套使用的OpenCV版本: 2.4.8


上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换。

所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,如开闭运算、形态学梯度、“顶帽”、“黑帽”等等。

 先上几张示例程序的截图吧:


有没有很熟悉这张图?没错,这就是最近热映的电影Captain America~

下面这张图的效果就有些凶残了:

OK,截图先看到这里。在正文之前先来唠唠和主题相关的事情。


第一件事,OpenCV最新版本更新到了2.4.9。


在写这篇博文的两天之前(4月25日上午),OpenCV官网页面显示最新版本还是2.4.8,但是通过浅墨细心地发现,文档页面的标题已经悄悄而低调地改成了2.4.9.所以我们当时应该可以去断定,OpenCV2.4.9应该马上就要和我们见面了。

 

果然,OpenCV2.4.9就在两天后(4月27日),正式在OpenCV官方网站上上线了。现在转到OpenCV的官方主页,赫然发现最新版本已然显示为2.4.9:

这是OpenCV的官方主页传送门:http://opencv.org/

大家可以自己前去看看以及下载最新版本的OpenCV。如果不出意外的话呢,下次文章我们就将紧跟时代,用上最新版本的OpenCV2.4.9进行讲解和程序的书写,所以,大家在看这篇文章之后呢,可以去下载当前最新的2.4.9版本并装上配置好。




第二件事,是浅墨想跟大家做一个关于OpenCV系列文章的书写内容和风格的思想汇报。


是这样的,浅墨发现最近几期写出来的文章有些偏离自己开始开这个专栏的最初的愿望——原理和概念部分占的比重有些大,有些弱化OpenCV实际的使用。

写这些博文的初心是教大家如何使用OpenCV来写代码,原理部分我想很多朋友应该多少都懂,就算某些同学对某些概念有些模糊,大家也完全可以带着关键词句去google或者百度。

浅墨的想法是,以后的专栏文章原理部分尽量从简,“深入”的源码剖析部分也是从简,重点突出“浅出”部分,让大家快速上手OpenCV函数的使用,这样浅墨的工作量也会小很多,更新也会更勤。

PS:浅墨其实每次在写图像处理原理部分的时候都特纠结,因为浅墨其实感兴趣的和大家一样,也是如何写代码,而不是那些多多少少让人提不起兴趣来的图像处理公式和概念。这往往就照成了博文更新的拖延症。

所以呢,在浅墨以后写的OpenCV文章中,原理和深入部分我们就点到为止,文章的拳头内容是“浅出”部分,重点教大家如何快速上手OpenCV API。我想这也是大家一直期待和想要看到的浅墨出品的文章的样子吧。:)

OK,大概就是这些。我们开始今天的正题。






一、理论与概念讲解——从现象到本质



首先呢,要知道形态学的高级形态,往往都是建立在腐蚀和膨胀这两个基本操作之上的。而关于腐蚀和膨胀,概念和细节以及相关代码可以看浅墨之前写的这篇文章:


【OpenCV入门教程之十】 形态学图像处理(一):膨胀与腐蚀


对膨胀和腐蚀心中有数了,接下来的高级形态学操作,应该就不难理解。

另外,为了下面对比和演示以及理解的方便,浅墨自己制作了一张毛笔字图,这里先上原图:

 

 OK,我们开始讲解。





1.1 开运算(Opening Operation)

 



开运算(Opening Operation),其实就是先腐蚀后膨胀的过程。其数学表达式如下:




开运算可以用来消除小物体、在纤细点处分离物体、平滑较大物体的边界的同时并不明显改变其面积。效果图是这样的:

实际效果图:

 




1.2 闭运算(Closing Operation)


先膨胀后腐蚀的过程称为闭运算(Closing Operation),其数学表达式如下:

 

闭运算能够排除小型黑洞(黑色区域)。效果图如下所示:

 

实际效果图:





1.3 形态学梯度(MorphologicalGradient)


形态学梯度(Morphological Gradient)为膨胀图与腐蚀图之差,数学表达式如下:

 

对二值图像进行这一操作可以将团块(blob)的边缘突出出来。我们可以用形态学梯度来保留物体的边缘轮廓,如下所示:

 

实际素材效果图:





1.4 顶帽(Top Hat)


顶帽运算(Top Hat)又常常被译为”礼帽“运算。为原图像与上文刚刚介绍的“开运算“的结果图之差,数学表达式如下:

因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

顶帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。

如下所示:

素材效果图:

 

 



1.5 黑帽(Black Hat)



黑帽(Black Hat)运算为”闭运算“的结果图与原图像之差。数学表达式为:


黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。

所以,黑帽运算用来分离比邻近点暗一些的斑块。非常完美的轮廓效果图:

 

实际素材效果图:





 

二、深入——OpenCV源码分析溯源




本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和腐蚀技术,来执行更加高级的形态学变换,如开闭运算,形态学梯度,“顶帽”、“黑帽”等等。这一节我们来一起看一下morphologyEx函数的源代码。

[cpp]  view plain copy
print ? 在CODE上查看代码片 派生到我的代码片
  1. //-----------------------------------【erode()函数中文注释版源代码】----------------------------    
  2. //   说明:以下代码为来自于计算机开源视觉库OpenCV的官方源代码    
  3. //   OpenCV源代码版本:2.4.8    
  4. //   源码路径:…\opencv\sources\modules\imgproc\src\morph.cpp    
  5. //   源文件中如下代码的起始行数:1369行    
  6. //   中文注释by浅墨    
  7. //--------------------------------------------------------------------------------------------------------     
  8. void cv::morphologyEx( InputArray _src,OutputArray _dst, int op,  
  9.                        InputArray kernel, Pointanchor, int iterations,  
  10.                        int borderType, constScalar& borderValue )  
  11. {  
  12. //拷贝Mat数据到临时变量  
  13.    Mat src = _src.getMat(), temp;  
  14.    _dst.create(src.size(), src.type());  
  15.    Mat dst = _dst.getMat();  
  16.    
  17. //一个大switch,根据不同的标识符取不同的操作  
  18.    switch( op )  
  19.     {  
  20.    case MORPH_ERODE:  
  21.        erode( src, dst, kernel, anchor, iterations, borderType, borderValue );  
  22.        break;  
  23.    case MORPH_DILATE:  
  24.        dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );  
  25.        break;  
  26.    case MORPH_OPEN:  
  27.        erode( src, dst, kernel, anchor, iterations, borderType, borderValue );  
  28.        dilate( dst, dst, kernel, anchor, iterations, borderType, borderValue );  
  29.        break;  
  30.    case CV_MOP_CLOSE:  
  31.        dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );  
  32.        erode( dst, dst, kernel, anchor, iterations, borderType, borderValue );  
  33.        break;  
  34.    case CV_MOP_GRADIENT:  
  35.        erode( src, temp, kernel, anchor, iterations, borderType, borderValue );  
  36.        dilate( src, dst, kernel, anchor, iterations, borderType, borderValue );  
  37.        dst -= temp;  
  38.        break;  
  39.    case CV_MOP_TOPHAT:  
  40.        if( src.data != dst.data )  
  41.            temp = dst;  
  42.        erode( src, temp, kernel, anchor, iterations, borderType, borderValue );  
  43.         dilate( temp, temp, kernel, anchor,iterations, borderType, borderValue );  
  44.        dst = src - temp;  
  45.        break;  
  46.    case CV_MOP_BLACKHAT:  
  47.        if( src.data != dst.data )  
  48.            temp = dst;  
  49.        dilate( src, temp, kernel, anchor, iterations, borderType, borderValue);  
  50.        erode( temp, temp, kernel, anchor, iterations, borderType, borderValue);  
  51.        dst = temp - src;  
  52.        break;  
  53.    default:  
  54.        CV_Error( CV_StsBadArg, "unknown morphological operation" );  
  55.     }  
  56. }  

看上面的源码可以发现,其实morphologyEx函数其实就是内部一个大switch而已。根据不同的标识符取不同的操作。比如开运算MORPH_OPEN,按我们上文中讲解的数学表达式,就是先腐蚀后膨胀,即依次调用erode和dilate函数,为非常简明干净的代码。


本系列文章由@浅墨_毛星云 出品,转载请注明出处。  

文章链接: http://blog.csdn.net/poem_qianmo/article/details/23184547

作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442

知乎:http://www.zhihu.com/people/mao-xing-yun

邮箱: happylifemxy@163.com

写作当前博文时配套使用的OpenCV版本: 2.4.8

这篇关于形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538177

相关文章

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

✨机器学习笔记(二)—— 线性回归、代价函数、梯度下降

1️⃣线性回归(linear regression) f w , b ( x ) = w x + b f_{w,b}(x) = wx + b fw,b​(x)=wx+b 🎈A linear regression model predicting house prices: 如图是机器学习通过监督学习运用线性回归模型来预测房价的例子,当房屋大小为1250 f e e t 2 feet^

【Java中的位运算和逻辑运算详解及其区别】

Java中的位运算和逻辑运算详解及其区别 在 Java 编程中,位运算和逻辑运算是常见的两种操作类型。位运算用于操作整数的二进制位,而逻辑运算则是处理布尔值 (boolean) 的运算。本文将详细讲解这两种运算及其主要区别,并给出相应示例。 应用场景了解 位运算和逻辑运算的设计初衷源自计算机底层硬件和逻辑运算的需求,它们分别针对不同的处理对象和场景。以下是它们设计的初始目的简介:

位运算:带带孩子吧,孩子很强的!

快速进制 在聊到位运算之前,不妨先简单过一遍二进制的东西。熟悉二进制和十进制的快速转换确实是掌握位运算的基础,因为位运算直接在二进制位上进行操作。如果不熟悉二进制表示,很难直观理解位运算的效果。 这里主要涉及二进制和十进制之间的互相转换。 十进制转二进制 十进制转二进制可以使用常见的 除2取余法 进行。每次将十进制除以2并记录所得余数,直到商为0,然后再将记录的余数 从下往上排列即

AI学习指南深度学习篇-带动量的随机梯度下降法的基本原理

AI学习指南深度学习篇——带动量的随机梯度下降法的基本原理 引言 在深度学习中,优化算法被广泛应用于训练神经网络模型。随机梯度下降法(SGD)是最常用的优化算法之一,但单独使用SGD在收敛速度和稳定性方面存在一些问题。为了应对这些挑战,动量法应运而生。本文将详细介绍动量法的原理,包括动量的概念、指数加权移动平均、参数更新等内容,最后通过实际示例展示动量如何帮助SGD在参数更新过程中平稳地前进。

参会邀请 | 第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)

第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)将于2024年9月13日-15日在中国张家口召开。 MVIPIT 2024聚焦机器视觉、图像处理与影像技术,旨在为专家、学者和研究人员提供一个国际平台,分享研究成果,讨论问题和挑战,探索前沿技术。诚邀高校、科研院所、企业等有关方面的专家学者参加会议。 9月13日(周五):签到日 9月14日(周六):会议日 9月15日(周日

AI学习指南深度学习篇-带动量的随机梯度下降法简介

AI学习指南深度学习篇 - 带动量的随机梯度下降法简介 引言 在深度学习的广阔领域中,优化算法扮演着至关重要的角色。它们不仅决定了模型训练的效率,还直接影响到模型的最终表现之一。随着神经网络模型的不断深化和复杂化,传统的优化算法在许多领域逐渐暴露出其不足之处。带动量的随机梯度下降法(Momentum SGD)应运而生,并被广泛应用于各类深度学习模型中。 在本篇文章中,我们将深入探讨带动量的随

快速幂运算的一些模板

这里用递归和循环两种做法来做。 简单来说,快速幂就是把底数扩大,指数缩小,比如2*2=4;计算2的幂时,就可以转换成4的幂来运算,这样可以避免在计算大的数据时爆int的现象  //递归int power(int a,int n){int ans;if(n==2) ans=1;else{ans=power(a*a,n/2);if(n%2==1) ans*=a;}return ans;}

高精度计算----减法运算(浮点型)

基于上一贴,修改减法运算适合于高精度浮点型计算。 因为减法比加法难度大一点,考虑的地方也要多一些,可能代码有欠缺,欢迎指出。 运算说明: 1、相减函数依旧没改变,包括上一贴的判断被减数与减数的大小函数也没变。 2、增加两个函数,取小数位数函数和结果处理(回归小数点)函数 3、与加法浮点高精度运算相比,这里改变较多的是结果处理函数,加法加完后,位数不减反增,而且最多增一位。减法会消失掉好多