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

article/2025/8/29 5:30:40

形态学操作就是基于形状的一系列图像处理操作。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:
\f[\texttt{dst} (x,y) = \max _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')\f]

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:

\texttt{dst} (x,y) = \min _{(x',y'): \, \texttt{element} (x',y') \ne0 } \texttt{src} (x+x',y+y')

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 是锚点的位置,默认值为\f$(-1, -1)\f$

比如:

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)

参考文章:

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


http://chatgpt.dhexx.cn/article/O8TCN6vk.shtml

相关文章

C++ 膨胀与腐蚀(dilate、erode)

参考&#xff1a;https://blog.csdn.net/poem_qianmo/article/details/23710721 膨胀&#xff1a; 函数&#xff1a;一般只需输前三个参数&#xff1a;输入图像、输出图像、卷积内核 void dilate( InputArray src, OutputArray dst, InputArray kernel, Po…

PYTORCH 笔记 DILATE 代码解读

dilate 完整代码路径&#xff1a;vincent-leguen/DILATE: Code for our NeurIPS 2019 paper "Shape and Time Distortion Loss for Training Deep Time Series Forecasting Models" (github.com) 1 main 函数 1.1 导入库 import numpy as np import torch from da…

Opencv中的erode和dilate(腐蚀和膨胀-python实现)

文章目录 1.腐蚀原理&#xff08;1&#xff09;具体实现过程&#xff08;2&#xff09;.函数讲解 &#xff08;3&#xff09;.代码实战2.膨胀原理&#xff08;1&#xff09;具体实现过程&#xff08;2&#xff09;函数讲解&#xff08;3&#xff09;代码实现 1.腐蚀原理 &…

OpenCV-Python腐蚀膨胀函数erode、dilate使用详解

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一、引言 在《OpenCV-Python图像处理&#xff1a;腐蚀和膨胀原理及erode、dilate函数介绍&#xff1a;https://blog.csdn.net/LaoYuanPython/article/details/109441709》介绍了图像腐蚀和膨胀的基本原理&a…

OpenCV-Python图像处理:腐蚀和膨胀原理及erode、dilate函数介绍

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一、引言 关于图像的腐蚀和膨胀&#xff0c;网上介绍的资料非常多&#xff0c;老猿也看了很多&#xff0c;总体来说主要偏向于就使用OpenCV腐蚀和膨胀函数的应用&#xff0c;另外原理介绍的有一小部分&#…

opencv之dilate()函数

概述 dilate()函数可以对输入图像用特定结构元素进行膨胀操作,该结构元素确定膨胀操作过程中的邻域的形状,各点像素值将被替换为对应邻域上的最大值: API说明 C++ API: void cv::dilate(InputArraysrc,(原始图像:通道数不限,depth必须是CV_8U,CV_16U,CV_16S,CV_…

OpenCV-膨胀cv::dilate

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 原理 形态学是图像处理中常见的名词&#xff0c;图像处理的形态学基本属于数学形态学的范畴&#xff0c;是一门建立在格论和拓扑…

【图像处理】腐蚀(erode)和膨胀(dilate)

【图像处理】腐蚀&#xff08;erode&#xff09;和膨胀&#xff08;dilate&#xff09; 原理腐蚀&#xff08;erode&#xff09;膨胀&#xff08;dilate&#xff09; OpenCV实现C实现python实现 开运算&#xff08;Opening Operation&#xff09;闭运算&#xff08;Closing Ope…

chatgpt赋能Python-python_dilate

Python中的dilate操作&#xff1a;了解该操作及其应用 在计算机视觉领域&#xff0c;dilate操作是一种常用的图像处理技术。在Python中&#xff0c;我们可以使用OpenCV库来实现dilate操作。本文将介绍dilate操作的基本概念&#xff0c;讨论其应用及如何使用Python进行实现。 …

OPenCV膨胀函数dilate()的使用

OPenCV版本&#xff1a;4.4 IDE&#xff1a;VS2017 功能描述 简述&#xff1a;使用一个指定的核元素去膨胀一个图像&#xff0c;图像膨胀的过程类似于一个卷积的过程&#xff0c;源图像矩阵A以及结构元素B&#xff0c;B在A矩阵上依次移动&#xff0c;每个位置上B所覆盖元素的最…

OpenCV每日函数 图像过滤模块 (5) dilate膨胀函数

一、概述 通过使用特定的结构元素来扩大图像。该函数使用指定的结构元素扩展源图像,该结构元素确定取最大值的像素邻域的形状: 膨胀可以应用数次(迭代)。 在多通道图像的情况下,每个通道都是独立处理的。 膨胀: 腐蚀: 二、dilate函数 1、函数原型 cv::dilate…

生产环境屏蔽swagger

只需要在swagger的配置类上增加Profile( )注解&#xff0c;指定环境变量&#xff0c;即可屏蔽生产环境上的swagger&#xff0c;如下&#xff1a; 先使用dev环境&#xff0c;访问swagger&#xff0c;结果如下&#xff1a; 再使用test环境&#xff0c;访问swagger&#xff0c;结果…

生产环境解决跨域

1.先决条件是在开发环境中使用的是代理。 2然后在生产环境当中&#xff0c;增加一个proxy代理&#xff1b; &#xff08;1&#xff09;先下载&#xff1a;cnpm install http-proxy-middleware -D &#xff08;2&#xff09;引入&#xff1a; &#xff08;3&#xff09;使用&am…

linux环境下编译部署php生产环境

linux环境下编译部署php生产环境 版本控制 php&#xff1a;7.2.4 nginx&#xff1a;1.9.9 部分插件版本 xlswriter&#xff1a;1.3.3.2 redis:3.1.3 一、安装php 1.安装依赖(之后安装缺少的依赖都可以用yum安装) yum install -y gcc gcc-c make zlib zlib-devel pcre pcre…

用 source map 调试生产环境

当我们的应用程序部署到生产环境时&#xff0c;我们发现它与我们在开发环境时的代码不同。我们的代码在构建过程中会以各种方式进行修改和优化。 TypeScript 被转译、压缩。生成的 JavaScript 包尽可能小并且能够在浏览器中正常运行。 所有这些步骤都很有效率&#xff0c;它们…

uniapp 小程序 开发环境和生产环境

uni开发小程序 运行到开发工具 再上传 process.env.NODE_ENV 获取的值是development 一直是开发环境 用uni发行 上传到微信公众平台是生成环境 在 HBuilderX 中&#xff0c;点击“运行”编译出来的代码是开发环境&#xff0c;点击“发行”编译出来的代码是生产环境 let url;if …

Vue cli3配置生产环境,开发环境,和测试环境

目录1、先在package.json文件中添加&#xff1a; 2、在项目目录下建立 .env文件和.env.test文件 3、配置api变量 3.1、配置axios的baseURL路径 3.2、自己拼接的路径 4、.env知识点补充 4.1&#xff0c;关于文件名&#xff1a;必须以如下方式命名&#xff0c;不要…

31 SpringBoot多环境的切换(生产环境、开发环境、测试环境)

参考链接&#xff1a; Spring官网 Spring官网 外部配置加载顺序的说明 SpringBoot多环境的切换(生产环境、开发环境、测试环境)_周太阳的博客-CSDN博客_springboot测试生产环境切换 java maven 测试生产环境配置_SpringBoot生产环境和测试环境配置分离的教程详解_落云歌语文…

生产环境关闭 swagger

#生产环境需要关闭 swagger 防止接口暴露 1&#xff0c;启动判断写在相应的环境配置文件中&#xff0c;根据条件判断是否启动 swagger &#xff1a; 添加配置项&#xff1a;swagger.is.enable #是否激活 swagger true or false swagger.is.enabletrue2&#xff0c;代码取值&a…

前端工程师生产环境 debugger 技巧

关注公众号 前端开发博客&#xff0c;领27本电子书 回复加群&#xff0c;自助秒进前端群 导言 开发环境 debug 是每个程序员上岗的必备技能。生产环境呢&#xff1f;虽然生产环境 debug 是一件非常不优雅的行为&#xff0c;但是由于种种原因&#xff0c;我们又不得不这么干。 那…