形态学操作就是基于形状的一系列图像处理操作。OpenCV为进行图像的形态学变换提供了快捷、方便的函数。最基本的形态学操作有二种,他们是:膨胀与腐蚀(Dilation与Erosion)。

膨胀与腐蚀能实现多种多样的功能,主要如下:

  • 消除噪声
  • 分割(isolate)出独立的图像元素,在图像中连接(join)相邻的元素。
  • 寻找图像中的明显的极大值区域或极小值区域
  • 求出图像的梯度

腐蚀和膨胀是针对白色部分(高亮部分)而言的。

  • 膨胀就是对图像高亮部分进行“领域扩张”,效果图拥有比原图更大的高亮区域;
  • 腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域。

膨胀用来处理缺陷问题; 腐蚀用来处理毛刺问题。

膨胀dilate

膨胀就是求局部最大值的操作,从图像直观看来,就是将图像光亮部分放大,黑暗部分缩小。

按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为A)与核(我们称之为B)进行卷积。假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,以B覆盖下A的最大像素值(偏白)替换锚点的像素,其中B作为结构体可以是任意形状(与卷积不同之处,可以是线、矩阵、圆、十字等形状)

二值图像与灰度图像上的膨胀操作:

腐蚀erode

腐蚀操作和膨胀操作相反,也就是将毛刺消除,腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值(偏黑)替换锚点重叠下图像的像素值。


void cv::erode( InputArray src, OutputArraydst, InputArray kernel,Point anchor, int iterations,int borderType, constScalar& borderValue )
{
//调用morphOp函数,并设定标识符为MORPH_ERODEmorphOp( MORPH_ERODE, src, dst, kernel, anchor, iterations, borderType,borderValue );
}void cv::dilate( InputArray src,OutputArray dst, InputArray kernel,Point anchor, int iterations,int borderType, constScalar& borderValue )
{
//调用morphOp函数,并设定标识符为MORPH_DILATEmorphOp( MORPH_DILATE, src, dst, kernel, anchor, iterations, borderType,borderValue );
}

可以发现erode和dilate这两个函数内部就是调用了一下morphOp,只是他们调用morphOp时,第一个参数标识符不同,一个为MORPH_ERODE(腐蚀),一个为MORPH_DILATE(膨胀)。

形态学膨胀——dilate函数

函数原型:

void dilate(InputArray src,OutputArray dst,InputArray kernel,Point anchor=Point(-1,-1),int iterations=1,int borderType=BORDER_CONSTANT,const Scalar& borderValue=morphologyDefaultBorderValue()
);

/** @brief Dilates an image by using a specific structuring element.

The function dilates the source image using the specified structuring element that determines the
shape of a pixel neighborhood over which the maximum is taken:

The function supports the in-place mode. Dilation can be applied several ( iterations ) times. In
case of multi-channel images, each channel is processed independently.

@param src input image; the number of channels can be arbitrary, but the depth should be one of
CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param kernel structuring element used for dilation; if element=Mat(), a 3 x 3 rectangular structuring element is used. Kernel can be created using #getStructuringElement
@param anchor position of the anchor within the element; default value (-1, -1) means that the anchor is at the element center.
@param iterations number of times dilation is applied.
@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not suported.
@param borderValue border value in case of a constant border

参数详解:

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray类型的kernel,膨胀操作的核。若为NULL时,表示的是使用参考点位于中心3x3的核。

我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。

其中,getStructuringElement函数的第一个参数表示内核的形状,我们可以选择如下三种形状之一:

  • 矩形: MORPH_RECT
  • 交叉形: MORPH_CROSS
  • 椭圆形: MORPH_ELLIPSE

而getStructuringElement函数的第二和第三个参数分别是内核的尺寸以及锚点的位置。

我们一般在调用erode以及dilate函数之前,先定义一个Mat类型的变量来获得getStructuringElement函数的返回值。对于锚点的位置,有默认值Point(-1,-1),表示锚点位于中心。且需要注意,十字形的element形状唯一依赖于锚点的位置。而在其他情况下,锚点只是影响了形态学运算结果的偏移。

getStructuringElement函数相关的调用示例代码如下:

 int g_nStructElementSize = 3; //结构元素(内核矩阵)的尺寸//获取自定义核
Mat element = getStructuringElement(MORPH_RECT,Size(2*g_nStructElementSize+1,2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));

调用这样之后,我们便可以在接下来调用erode或dilate函数时,第三个参数填保存了getStructuringElement返回值的Mat类型变量。对应于我们上面的示例,就是填element变量。

  • 第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于中心。
  • 第五个参数,int类型的iterations,迭代使用erode()函数的次数,默认值为1。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
  • 第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。

使用erode函数,一般我们只需要填前面的三个参数,后面的四个参数都有默认值。而且往往结合getStructuringElement一起使用。

调用范例:

         //载入原图 Mat image = imread("1.jpg");//获取自定义核Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));Mat out;//进行膨胀操作dilate(image, out, element);
//-----------------------------------【头文件包含部分】---------------------------------------
//     描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>//-----------------------------------【命名空间声明部分】---------------------------------------
//     描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace std;
using namespace cv;//-----------------------------------【main( )函数】--------------------------------------------
//     描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{//载入原图 Mat image = imread("5.jpg");//显示原图imshow("【原图】膨胀操作", image);//获取自定义核Mat element1 = getStructuringElement(MORPH_RECT, Size(7, 7));Mat element2 = getStructuringElement(MORPH_RECT, Size(15, 15));Mat out1;Mat out2;//进行膨胀操作dilate(image, out1, element1);dilate(image, out2, element2);//显示效果图imshow("【效果图】膨胀操作(ksize=5)", out1);imshow("【效果图】膨胀操作(ksize=15)", out2);waitKey(0);return 0;
}

可以看到白色的像素点(像素值高的像素点)越来越多,黑色的部分(像素值低的像素点)越来越少。 

形态学腐蚀——erode函数

C++: void erode(InputArray src,OutputArray dst,InputArray kernel,Point anchor=Point(-1,-1),int iterations=1,int borderType=BORDER_CONSTANT,const Scalar& borderValue=morphologyDefaultBorderValue());

/** @brief Erodes an image by using a specific structuring element.

The function erodes the source image using the specified structuring element that determines the
shape of a pixel neighborhood over which the minimum is taken:

The function supports the in-place mode. Erosion can be applied several ( iterations ) times. In
case of multi-channel images, each channel is processed independently.

@param src input image; the number of channels can be arbitrary, but the depth should be one of
CV_8U, CV_16U, CV_16S, CV_32F or CV_64F.
@param dst output image of the same size and type as src.
@param kernel structuring element used for erosion; if `element=Mat()`, a `3 x 3` rectangular
structuring element is used. Kernel can be created using #getStructuringElement.
@param anchor position of the anchor within the element; default value (-1, -1) means that the
anchor is at the element center.
@param iterations number of times erosion is applied.
@param borderType pixel extrapolation method, see #BorderTypes. #BORDER_WRAP is not supported.
@param borderValue border value in case of a constant border

参数详解:

  • 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。图像通道的数量可以是任意的,但图像深度应为CV_8U,CV_16U,CV_16S,CV_32F或 CV_64F其中之一。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,InputArray类型的kernel,腐蚀操作的内核。若为NULL时,表示的是使用参考点位于中心3x3的核。我们一般使用函数 getStructuringElement配合这个参数的使用。getStructuringElement函数会返回指定形状和尺寸的结构元素(内核矩阵)。
  • 第四个参数,Point类型的anchor,锚的位置,其有默认值(-1,-1),表示锚位于单位(element)的中心,我们一般不用管它。
  • 第五个参数,int类型的iterations,迭代使用erode()函数的次数,默认值为1。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。
  • 第七个参数,const Scalar&类型的borderValue,当边界为常数时的边界值,有默认值morphologyDefaultBorderValue(),一般我们不用去管他。需要用到它时,可以看官方文档中的createMorphologyFilter()函数得到更详细的解释。

同样的,使用erode函数,一般我们只需要填前面的三个参数,后面的四个参数都有默认值。而且往往结合getStructuringElement一起使用。

         //载入原图 Mat image = imread("1.jpg");//获取自定义核Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));Mat out;//进行腐蚀操作erode(image,out, element);
//-----------------------------------【头文件包含部分】---------------------------------------
//     描述:包含程序所依赖的头文件
//----------------------------------------------------------------------------------------------
#include <opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>//-----------------------------------【命名空间声明部分】---------------------------------------
//     描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace std;
using namespace cv;//-----------------------------------【main( )函数】--------------------------------------------
//     描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main(  )
{//载入原图 Matimage = imread("1.jpg");//创建窗口 namedWindow("【原图】腐蚀操作");namedWindow("【效果图】腐蚀操作");//显示原图imshow("【原图】腐蚀操作", image);//获取自定义核Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));Mat out;//进行腐蚀操作erode(image,out, element);//显示效果图imshow("【效果图】腐蚀操作", out);waitKey(0);return 0;
}

与膨胀相反,可以看到白色的像素点(像素值高的像素点)越来越少,黑色的部分(像素值低的像素点)越来越多。 

腐蚀膨胀辅助函数getStructuringElement

函数原型:

CV_EXPORTS_W Mat getStructuringElement(int shape, Size ksize, Point anchor = Point(-1,-1));
Returns a structuring element of the specified size and shape for morphological operations.返回指定形状和尺寸的结构元素。The function constructs and returns the structuring element that can be further passed to #erode,
#dilate or #morphologyEx. But you can also construct an arbitrary binary mask yourself and use it as
the structuring element.@param shape Element shape that could be one of #MorphShapes
@param ksize Size of the structuring element.
@param anchor Anchor position within the element. The default value means that the
anchor is at the center. Note that only the shape of a cross-shaped element depends on the anchor
position. In other cases the anchor just regulates how much the result of the morphological
operation is shifted.

第一个参数shape 表示内核的形状,有三种形状可以选择。

  • 矩形:MORPH_RECT;
  • 交叉形:MORPH_CROSS;
  • 椭圆形:MORPH_ELLIPSE;

第二个参数ksize 是内核的尺寸

第三个参数anchor 是锚点的位置,默认值为

比如:

element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))

将会生成:

实际上这里是一个5 * 5的矩阵:

>>> import cv2
>>> element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
>>> element
array([[0, 0, 1, 0, 0],
          [0, 0, 1, 0, 0],
          [1, 1, 1, 1, 1],
          [0, 0, 1, 0, 0],
          [0, 0, 1, 0, 0]], dtype=uint8)

参考文章:

形态学图像处理(一):膨胀与腐蚀

opencv形态学运算:腐蚀(erode)和膨胀(dilate)相关推荐

  1. OpenCV图像处理形态学操作腐蚀Erode与膨胀Dilate

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 通俗的说 ...

  2. python opencv 腐蚀_opencv 图像的腐蚀(erode)和膨胀(dilate) 开运算以及闭运算

    原文链接:opencv 图像的腐蚀(erode)和膨胀(dilate) 开运算以及闭运算 OpenCV---开闭操作 - 山上有风景 - 博客园 腐蚀 : 腐蚀操作会把前景物体的边缘腐蚀掉.原理是卷积 ...

  3. OpenCV入门系列 —— cv::erode、cv::dilate 图像腐蚀和膨胀

    OpenCV入门系列 -- cv::erode.cv::dilate 图像腐蚀和膨胀 前言 程序说明 输出结果 代码示例 前言 随着工业自动化.智能化的不断推进,机器视觉(2D/3D)在工业领域的应用 ...

  4. OpenCV—形态学运算定义与实现

    OpenCV-形态学运算定义与实现 1.形态学运算与结构元素 形态学运算是针对二值图像依据数学形态学(Mathematical Morphology)的集合论方法发展起来的图像处理方法.数学形态学起源 ...

  5. OpenCV形态学运算

    1.OpenCV形态学运算morphologyEx(开运算 .闭运算 .形态学梯度 .顶帽运算 .黑帽运算 .腐蚀运算 .膨胀运算 .击中击不中运算) void cv::morphologyEx (I ...

  6. 图像腐蚀 java_OpenCV3 图像膨胀 dilate、腐蚀 erode、提取图像中的条形码 JAVA 实现...

    关于 JAVA 学习 OpenCV 的内容,函数讲解,案例代码内容我均整理在 GitHub[OpenCV3-Study-JAVA ]上 下面代码中所需的项目结构,图片,请访问 GitHub 获取. 代 ...

  7. 详解图像形态学操作之图形的腐蚀和膨胀的概念和运算过程,并利用OpenCV的函数erode()和函数dilate()对图像进行腐蚀和膨胀操作

    图像形态学中两种最基本的操作就是对图形的腐蚀和膨胀,可以说,形态学中的中高级操作都是建立在这两种操作之上.通过这两种基本的运算可以去除图像中的噪声,分割出独立的区域或者将两个区域连接在一起. 关于图像 ...

  8. opencv学习笔记12:图像腐蚀和图像膨胀

    语言:python+opencv 为什么使用图像腐蚀和图像膨胀 如图,使用图像腐蚀进行去噪,但是为压缩噪声. 对腐蚀过的图像,进行膨胀处理,可以去除噪声,并保持原样形状. 图像腐蚀 腐蚀主要针对的是二 ...

  9. opencv 形态学操作(python)

    形态学操作 形态学操作 腐蚀 膨胀 通用形态学函数 开运算 闭运算 形态学梯度运算 礼帽运算 黑帽运算 核函数 形态学操作 形态学,即数学形态学(Mathematical Morphology),是图 ...

最新文章

  1. Scott Mitchell 的ASP.NET 2.0数据教程之一: 创建一个数据访问层
  2. how to find the original page containing a given image
  3. java spring 单例模式,spring中的单例模式
  4. mysql 命令限制_MySQL 命令总结
  5. Spring MVC前端控制器不拦截静态资源配置
  6. web跨域问题解决方案
  7. 条件GAN论文简单解读
  8. 物联网卡平台系统由几部分构成
  9. Unity AnimatorController 混合树 状态机 骨骼
  10. javascript 实现下载的几种方法
  11. IQtree:使用 SNP 数据构建 有根 系统发育树及踩坑
  12. matlab矩阵与常数相乘,矩阵与常数的运算.ppt
  13. java简易计算器报告_简易计算器java实训报告.docx
  14. SOCKET 实现NAT 穿越
  15. BIM究竟是什么?为什么设计院还不能普及BIM做设计?
  16. centos-linux(64位)安装与配置
  17. 红旗linux 安装教程,红旗linux安装教程,红旗linux9
  18. Android获取酷狗音乐歌曲详细信息
  19. java怎么提升编程能力_怎样提升java编程能力
  20. 如何从零开始学Java

热门文章

  1. Excel数据的分类汇总
  2. 动量因子(Momentum factor)——投资组合分析(EAP.portfolio_analysis)
  3. c语言作业格式,C语言作业.doc
  4. 尚品汇商城_的后台首页
  5. 双系统系列:一. 模拟器wine
  6. 学黑客必去的网站“黑客基地”
  7. 《关于建立统一的城乡居民基本养老保险制度的意见》
  8. Steam Dota2 安装方法以及一些设置·
  9. 人机对话技术研究进展与思考
  10. 华为交换机/路由器用户名密码配置