OpenCV-Python教程:形态学变换~腐蚀和膨胀(erode,dilate)

article/2025/8/28 23:13:00

原文链接:http://www.juzicode.com/opencv-python-erode-dilate

返回Opencv-Python教程

形态学变换是基于图像形状的变换过程,通常用来处理二值图像,当然也可以用在灰度图上。OpenCV中的形态学变换同平滑处理一样也是基于一种“滑动窗口”的操作,不过在形态学变换中“滑动窗口”有一个更专业的名词:“结构元”,也可以像平滑处理那样称呼为kernel,结构元的形状有方形、十字形、椭圆形等,其形状决定了形态学变换的特点。形态学变换主要有腐蚀、膨胀、开操作、闭操作等等。

1、腐蚀erode()

腐蚀操作可以将边界的白色(前景)像素“腐蚀”掉,但仍能保持大部分白色。类似平滑处理的滑动窗口,用某种结构元在图像上滑动,当结构元覆盖原始图像中的所有像素都为“1”时,新图像中该像素点的值才为“1”(CV8U为255)。腐蚀可以用来去除噪声、去掉“粘连”。

接口形式:

cv2.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) ->dst
  • 参数含义:
  • src:通道数任意;图像深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F;
  • kernel:可以由getStructuringElement()构建;
  • dst:输出图像,通道数和数据类型同src;
  • anchor:锚点,默认使用(-1,-1)表示中心点;
  • iterations:腐蚀次数;
  • borderType:边界类型;
  • borderValue:边界值;

下面是一个kernel大小为5和7的腐蚀例子:

import matplotlib.pyplot as plt 
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7.jpg',cv2.IMREAD_GRAYSCALE) 
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) #ksize=5,5
img_ret1 = cv2.erode(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7)) #ksize=7x7,
img_ret2 = cv2.erode(img,kernel,iterations=1)
img_ret3 = cv2.erode(img,kernel,iterations=2) #ksize=7x7,腐蚀2次#显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图-mnist(juzicode.com)')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('erode ksize=5')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('erode ksize=7')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('erode ksize=7 iter=2') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

运行结果:

原图图源:mnist

 从运行结果可以看到kernel的ksize越大,iterations次数越多,图像看起来越“廋”。

2、膨胀dilate()

膨胀是腐蚀的逆操作,可以将边界的白色(前景)像素“生长”扩大。滑动窗口经过白色像素时,只要结构元中有1个像素为“1”时,新图像中该像素点的值就为“1”(CV8U为255)。膨胀可以用来增强连接、填充凹痕。

接口形式:

cv2.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) ->dst
  • 参数含义:
  • src:通道数任意;图像深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F;
  • kernel:可以由getStructuringElement()构建;
  • dst:输出图像,通道数和数据类型同src;
  • anchor:锚点,默认使用(-1,-1)表示中心点;
  • iterations:腐蚀次数;
  • borderType:边界类型;
  • borderValue:边界值;

下面是一个kernel大小为5和7的膨胀例子:

import matplotlib.pyplot as plt 
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7-b.jpg',cv2.IMREAD_GRAYSCALE) 
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
img_ret1 = cv2.dilate(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
img_ret2 = cv2.dilate(img,kernel,iterations=1)
img_ret3 = cv2.dilate(img,kernel,iterations=2) #显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图-mnist(juzicode.com)')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('dilate ksize=5')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('dilate ksize=7')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('dilate ksize=7 iter=2') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

运行结果:

原图图源:mnist

 从运行结果可以看到kernel的ksize越大,iterations次数越多,图像看起来越“胖”。

3、结构元生成getStructuringElement()

结构元生成函数用来生成形态学变换的kernel参数。

接口形式:

cv2.getStructuringElement(shape, ksize[, anchor]) ->retval
  • 参数含义:
  • shape:结构元(kernel)的形状;
  • ksize:结构元(kernel)的大小;
  • anchor:锚点,默认使用(-1,-1)表示中心点;

其中shape属性有可选的3种形状:

cv2.MORPH_RECT方形,所有的数值均为1
cv2.MORPH_CROSS十字交叉形,在锚点坐标的水平和竖直方向的元素为1,其他为0
cv2.MORPH_ELLIPSE椭圆形

下面是一个kernel大小为7,形状不同的膨胀例子:

import matplotlib.pyplot as plt 
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7-b.jpg',cv2.IMREAD_GRAYSCALE) 
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
print('MORPH_RECT kernel:\n',kernel)
img_ret1 = cv2.dilate(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(7,7))
print('MORPH_ELLIPSE kernel:\n',kernel)
img_ret2 = cv2.dilate(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7))
print('MORPH_CROSS kernel:\n',kernel)
img_ret3 = cv2.dilate(img,kernel,iterations=1) #显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图-mnist(juzicode.com)')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('MORPH_RECT kernel')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('MORPH_ELLIPSE kernel')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('MORPH_CROSS kernel') 
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show() 

运行结果:

VX公众号: 桔子code / juzicode.com
cv2.__version__: 4.5.3
MORPH_RECT kernel:[[1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1]]
MORPH_ELLIPSE kernel:[[0 0 0 1 0 0 0][0 1 1 1 1 1 0][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][0 1 1 1 1 1 0][0 0 0 1 0 0 0]]
MORPH_CROSS kernel:[[0 0 0 1 0 0 0][0 0 0 1 0 0 0][0 0 0 1 0 0 0][1 1 1 1 1 1 1][0 0 0 1 0 0 0][0 0 0 1 0 0 0][0 0 0 1 0 0 0]]

原图图源:mnist

从运行结果可以看到当使用方形MORPH_RECT的结构元时,新图像的边界看起来仍然是方方正正的,但是使用十字形MORPH_CROSS和椭圆形MORPH_ELLIPSE的结构元时,边界要显得“圆滑”的多。

4、实际应用的例子

下面是一个用腐蚀去除噪声的例子:

import matplotlib.pyplot as plt 
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7-noise.jpg',cv2.IMREAD_GRAYSCALE) 
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
img_ret1 = cv2.erode(img,kernel,iterations=2) #显示图像
fig,ax = plt.subplots(1,2)
ax[0].set_title('原图 (juzicode.com)')
ax[0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[1].set_title('erode ksize=7 iter=2') 
ax[1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[0].axis('off');ax[1].axis('off')
plt.show() 

原图图源:mnist

在原图中白色小点表示的噪声通过腐蚀操作被去除掉了。

下面是一个在五线谱中去除横线的例子:

import matplotlib.pyplot as plt 
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\data\\notes.png',cv2.IMREAD_GRAYSCALE) 
_,img_bin = cv2.threshold(img,127,255,1)#二值反色
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,7))
img_erode = cv2.erode(img_bin,kernel,iterations=1) 
img_dilate = cv2.dilate(img_erode,kernel,iterations=1) #显示图像
fig,ax = plt.subplots(3,1)
ax[0].set_title('原图 (juzicode.com)')
ax[0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[1].set_title('img_erode') 
ax[1].imshow(cv2.cvtColor(img_erode,cv2.COLOR_BGR2RGB))
ax[2].set_title('img_dilate') 
ax[2].imshow(cv2.cvtColor(img_dilate,cv2.COLOR_BGR2RGB))
ax[0].axis('off');ax[1].axis('off');ax[2].axis('off')
plt.show() 

因为横线是水平方向的,高度小长度大,先用一个1×7的结构元进行腐蚀,这时腐蚀会作用到垂直方向上,水平方向几乎不会被影响到,从而将高度较小的横线腐蚀掉,但是因为腐蚀操作将需要保留的符号也腐蚀掉了一部分,所以再用同样的结构元进行一次膨胀操作,就能复原出符号的形状。

扩展阅读:

  1. OpenCV-Python教程

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

相关文章

计算机视觉开源库OpenCV之cv2.erode()和cv2.dilate()函数

cv2.erode()腐蚀:将前景物体变小,理解成将图像断开裂缝变大(在图片上画上黑色印记,印记越来越大) dst cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) cv2.dilate()膨胀&…

opencv-膨胀 dilate()

【功能】 膨胀是对白色部分(高亮部分)而言的,膨胀就是图像中的高亮部分进行膨胀,“领域扩张”,效果图拥有比原图更大的高亮区域。 膨胀是结构元素反射的平移与处理的图像的交集不为空。(结构元素B 与 图像…

OpenCvSharp函数:Dilate膨胀、GetStructuringElement获取形态操作的结构元素、Erode腐蚀

Dilate膨胀 函数说明:用特定的结构元素膨胀图像。膨胀可以看成是最大值滤波,即用最大值替换中心像素点。该函数就地模式,可以指定迭代次数,多通道图像的话,每个通道分开处理。 用3x3矩形结构元素膨胀 //函数原型 void …

OpenCV学习十一:dilate、erode 膨胀及腐蚀

膨胀及腐蚀,函数很简单,就写了个Demo 定义: 膨胀---图像膨胀的过程类似于一个卷积的过程,假设有图像矩阵A以及结构元素B(注意,B的形状、尺寸没有限制),B在A矩阵上依次移动&#xf…

OpenCV之图像膨胀:dilate函数(C++实现)

dilate函数是使用像素邻域内的局部极大运算符来膨胀图像。 函数原型: void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchorPoint(-1, -1), int iterations1, int borderTypeBORDER_CONSTANT, const Scalar& borderValuemorphology…

【Opencv--形态学操作】膨胀、腐蚀、开/闭操作:cv2.morphologyEx、cv2.erode、cv2.dilate

【Opencv–形态学操作】膨胀、腐蚀、开/闭操作 文章目录 【Opencv--形态学操作】膨胀、腐蚀、开/闭操作1. 介绍2. 形态学操作2.1 腐蚀和膨胀2.1.1 腐蚀2.1.2 膨胀2.1.3 代码示例 2.2 开/闭操作2.2.1 开操作2.2.2 闭操作2.2.3 代码示例 2.3 礼帽和黑帽2.3.1 礼帽运算2.3.2 黑帽运…

opencv 图像腐蚀膨胀 erode dilate

#include "iostream" #include "opencv2/opencv.hpp" using namespace std; using namespace cv;int main() {Mat img, dst, dstbin, distancetransform,rel, rel2;img imread("m3.jpg");//转为灰度图cvtColor(img, dst, COLOR_BGR2GRAY);//二…

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() ) 函…

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

形态学操作就是基于形状的一系列图像处理操作。OpenCV为进行图像的形态学变换提供了快捷、方便的函数。最基本的形态学操作有二种,他们是:膨胀与腐蚀(Dilation与Erosion)。 膨胀与腐蚀能实现多种多样的功能,主要如下: 消除噪声分…

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

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

PYTORCH 笔记 DILATE 代码解读

dilate 完整代码路径: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.腐蚀原理(1)具体实现过程(2).函数讲解 (3).代码实战2.膨胀原理(1)具体实现过程(2)函数讲解(3)代码实现 1.腐蚀原理 &…

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

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

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

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

opencv之dilate()函数

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

OpenCV-膨胀cv::dilate

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

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

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

chatgpt赋能Python-python_dilate

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

OPenCV膨胀函数dilate()的使用

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

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

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