opencv-图像形态学之开运算、闭运算、形态学梯度、顶帽、黑帽合辑
转自:https://blog.csdn.net/poem_qianmo/article/details/24599073
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函数的源代码。
//-----------------------------------【erode()函数中文注释版源代码】---------------------------- // 说明:以下代码为来自于计算机开源视觉库OpenCV的官方源代码 // OpenCV源代码版本:2.4.8 // 源码路径:…\opencv\sources\modules\imgproc\src\morph.cpp // 源文件中如下代码的起始行数:1369行 // 中文注释by浅墨 //-------------------------------------------------------------------------------------------------------- void cv::morphologyEx( InputArray _src,OutputArray _dst, int op, InputArray kernel, Pointanchor, int iterations, int borderType, constScalar& borderValue ) { //拷贝Mat数据到临时变量 Mat src = _src.getMat(), temp; _dst.create(src.size(), src.type()); Mat dst = _dst.getMat(); //一个大switch,根据不同的标识符取不同的操作 switch( op ) { case MORPH_ERODE: erode( src, dst, kernel, anchor, iterations, borderType, borderValue ); break; case MORPH_DILATE: dilate( src, dst, kernel, anchor, iterations, borderType, borderValue ); break; case MORPH_OPEN: erode( src, dst, kernel, anchor, iterations, borderType, borderValue ); dilate( dst, dst, kernel, anchor, iterations, borderType, borderValue ); break; case CV_MOP_CLOSE: dilate( src, dst, kernel, anchor, iterations, borderType, borderValue ); erode( dst, dst, kernel, anchor, iterations, borderType, borderValue ); break; case CV_MOP_GRADIENT: erode( src, temp, kernel, anchor, iterations, borderType, borderValue ); dilate( src, dst, kernel, anchor, iterations, borderType, borderValue ); dst -= temp; break; case CV_MOP_TOPHAT: if( src.data != dst.data ) temp = dst; erode( src, temp, kernel, anchor, iterations, borderType, borderValue ); dilate( temp, temp, kernel, anchor,iterations, borderType, borderValue ); dst = src - temp; break; case CV_MOP_BLACKHAT: if( src.data != dst.data ) temp = dst; dilate( src, temp, kernel, anchor, iterations, borderType, borderValue); erode( temp, temp, kernel, anchor, iterations, borderType, borderValue); dst = temp - src; break; default: CV_Error( CV_StsBadArg, "unknown morphological operation" ); } }
看上面的源码可以发现,其实morphologyEx函数其实就是内部一个大switch而已。根据不同的标识符取不同的操作。比如开运算MORPH_OPEN,按我们上文中讲解的数学表达式,就是先腐蚀后膨胀,即依次调用erode和dilate函数,为非常简明干净的代码。
三、浅出——API函数快速上手
3.1 morphologyEx函数详解
上面我们已经讲到,morphologyEx函数利用基本的膨胀和腐蚀技术,来执行更加高级形态学变换,如开闭运算,形态学梯度,“顶帽”、“黑帽”等等。这一节我们来了解它的参数意义和使用方法。
C++: void morphologyEx( InputArray src, OutputArray dst, int op, InputArraykernel, Pointanchor=Point(-,-), intiterations=, intborderType=BORDER_CONSTANT, constScalar& borderValue=morphologyDefaultBorderValue() );
- 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像位深应该为以下五种之一:CV_8U, CV_16U,CV_16S, CV_32F 或CV_64F。
- 第二个参数,OutputArray类型的dst,即目标图像,函数的输出参数,需要和源图片有一样的尺寸和类型。
- 第三个参数,int类型的op,表示形态学运算的类型,可以是如下之一的标识符:
- MORPH_OPEN – 开运算(Opening operation)
- MORPH_CLOSE – 闭运算(Closing operation)
- MORPH_GRADIENT -形态学梯度(Morphological gradient)
- MORPH_TOPHAT - “顶帽”(“Top hat”)
- MORPH_BLACKHAT - “黑帽”(“Black hat“)
另有CV版本的标识符也可选择,如CV_MOP_CLOSE,CV_MOP_GRADIENT,CV_MOP_TOPHAT,CV_MOP_BLACKHAT,这应该是OpenCV1.0系列版本遗留下来的标识符,和上面的“MORPH_OPEN”一样的效果。
- 第四个参数,InputArray类型的kernel,形态学运算的内核。若为NULL时,表示的是使用参考点位于中心3x3的核。我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。关于getStructuringElement我们上篇文章中讲过了,这里为了大家参阅方便,再写一遍:
其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:
- 矩形: MORPH_RECT
- 交叉形: MORPH_CROSS
- 椭圆形: MORPH_ELLIPSE
而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。
我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。
getStructuringElement函数相关的调用示例代码如下:
int g_nStructElementSize = ; //结构元素(内核矩阵)的尺寸 //获取自定义核 Mat element =getStructuringElement(MORPH_RECT, Size(*g_nStructElementSize+,*g_nStructElementSize+), Point(g_nStructElementSize, g_nStructElementSize ));
调用这样之后,我们便可以在接下来调用erode、dilate或morphologyEx函数时,kernel参数填保存getStructuringElement返回值的Mat类型变量。对应于我们上面的示例,就是填element变量。
- 第五个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。
- 第六个参数,int类型的iterations,迭代使用函数的次数,默认值为1。
- 第七个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_ CONSTANT。
- 第八个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。
其中的这些操作都可以进行就地(in-place)操作。且对于多通道图像,每一个通道都是单独进行操作。
opencv-图像形态学之开运算、闭运算、形态学梯度、顶帽、黑帽合辑的更多相关文章
- 【OpenCV新手教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/23184547 作者:毛星云(浅墨) ...
- 学习 opencv---(10)形态学图像处理(2):开运算,闭运算,形态学梯度,顶帽,黒帽合辑
上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换. 所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和 ...
- paper 76:膨胀、腐蚀、开、闭运算——数字图像处理中的形态学
膨胀.腐蚀.开.闭运算是数学形态学最基本的变换.本文主要针对二值图像的形态学膨胀:把二值图像各1像素连接成分的边界扩大一层(填充边缘或0像素内部的孔):腐蚀:把二值图像各1像素连接成分的边界点去掉从而 ...
- 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...
- 机器学习进阶-图像形态学变化-礼帽与黑帽 1.cv2.TOPHAT(礼帽-原始图片-开运算后图片) 2.cv2.BLACKHAT(黑帽 闭运算-原始图片)
1.op = cv2.TOPHAT 礼帽:原始图片-开运算后的图片 2. op=cv2.BLACKHAT 黑帽: 闭运算后的图片-原始图片 礼帽:表示的是原始图像-开运算(先腐蚀再膨胀)以后的图像 ...
- opencv 4 图像处理(2 形态学滤波:腐蚀与膨胀,开运算、闭运算、形态学梯度、顶帽、黑帽)
腐蚀与膨胀 膨胀(求局部最大值)(dilate函数) #include <opencv2/core/core.hpp> #include <opencv2/highgui/highg ...
- opencv —— morphologyEx 开运算、闭运算、形态学梯度、顶帽、黑帽
开运算:先腐蚀后膨胀. 能够排除小亮点. 闭运算:先膨胀后腐蚀. 能够排除小黑点. 形态学梯度:膨胀图 — 腐蚀图. 对二值图像进行这一操作,可将图块的边缘突出出来,故可用来保留物体边缘轮廓. 顶帽: ...
- Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算
前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...
- OpenCV计算机视觉学习(5)——形态学处理(腐蚀膨胀,开闭运算,礼帽黑帽,边缘检测)
如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 形态 ...
随机推荐
- 线性基思想+贪心——cf1249C
/*1+3+9+...+3^n<3^(n+1),按这个思路贪心一下就好*/#include<bits/stdc++.h> using namespace std; #define l ...
- Sophus安装时Eigen库更新版本的问题
原文链接:https://blog.csdn.net/m0_38055352/article/details/102900516
- js 读取本地文件(必须通过input控件才能实现) 及 下载文件
js 操作 文件的实现原理: 1.js是不能直接操作(读写)文件的,html的 input[type="file"] 控件是可以读取文件数据(获取文件数据流)的.js可以获取这个 ...
- 剑指offer——二进制中1的个数(c++)
题目描述实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如,把9表示成二进制是1001,则输出为2 常规解法首先把n和1做位运算,判断n的最低位是不是1,然后把1左移一位得到2,再把n和2 ...
- 剑指offer---2、二叉搜索树的后序遍历序列
剑指offer---2.二叉搜索树的后序遍历序列 一.总结 一句话总结: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字 ...
- 解决Python报错:local variable 'xxx' referenced before assignment(引)
解决Python报错:local variable 'xxx' referenced before assignment(引) 解决Python报错:local variable 'xxx' refe ...
- PowerDesigner(数据库迁移)
PowerDesigner:导出SQL脚本以及问题解决在PowerDesigner中点击DataBase -----------> Generate Datebase -----(可以点击Pre ...
- 2019牛客多校第三场B-Crazy Binary String(前缀和+思维)
Crazy Binary String 题目传送门 解题思路 把1记为1,把0记为-1,然后求前缀和,前缀和相等的就说明中间的01数一样.只要记录前缀和数值出现的位置即可更新出答案. 代码如下 #in ...
- 洛谷 P2756 飞行员配对方案问题 (二分图匹配)
题目链接:P2756 飞行员配对方案问题 题意 给定 \(m\) 个外籍飞行员和 \(n - m\) 个英国飞行员,每一架飞机需要一名英国飞行员和一名外籍飞行员,求最多能派出几架飞机. 思路 最大流 ...
- 实验报告&总结
Java实验报告 班级计科二班 学号 20188429 姓名 罗璇哲 完成时间 评分等级 实验三 String类的应用 一. 实验目的 (1) 掌握类String类的使用: (2) 学会使用JDK帮助 ...