这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » OpenVINO生态社区 » 【原创】OpenCV-Python系列之图像腐蚀与膨胀(二十)

共3条 1/1 1 跳转至

【原创】OpenCV-Python系列之图像腐蚀与膨胀(二十)

高工
2020-06-29 21:06:06     打赏

OpenCV-Python系列之图像腐蚀与膨胀

我们在前两次教程中概述了OpenCV对于图像的滤波,通常对于一个实战项目而言,滤波之后的下一步操作就是图像的形态学处理了,从本次教程开始,我们正式步入了OpenCV图像形态学处理的部分。

形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构。而我们图像处理中指的形态学,往往表示的是数学形态学。下面一起来了解数学形态学的概念。

数学形态学是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。

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

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

1     消除噪声

2     分割出独立的图像元素,在图像中连接相邻的元素。

3     寻找图像中的明显的极大值区域或极小值区域

4     求出图像的梯度

腐蚀和膨胀是对白色部分(高亮部分)而言的,不是黑色部分。膨胀就是图像中的高亮部分进行膨胀,领域扩张,效果图拥有比原图更大的高亮区域。腐蚀就是原图中的高亮部分被腐蚀,领域被蚕食,效果图拥有比原图更小的高亮区域。

膨胀

其实,膨胀就是求局部最大值的操作。

按数学方面来说,膨胀或者腐蚀操作就是将图像(或图像的一部分区域,我们称之为A)与核(我们称之为B)进行卷积。

核可以是任何的形状和大小,它拥有一个单独定义出来的参考点,我们称其为锚点。多数情况下,核是一个小的中间带有参考点和实心正方形或者圆盘,其实,我们可以把核视为模板或者掩码。

而膨胀就是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长。如下图所示,这就是膨胀操作:

                                               image.png

我们来看一下函数原型:

cv2. dilate (img,kernel,iterations)->dst

第一个参数:img指需要膨胀的图

第二个参数:kernel指膨胀操作的内核,默认是一个简单的3X3矩阵,我们也可以利用getStructuringElement()函数指明它的形状

第三个参数:iterations指的是膨胀次数,省略是默认为1

dst则为返回的图像。

定义卷积核需要用到Numpy中的函数,它可以定义一个矩形的卷积核结构元素,我们来看一下代码:

import cv2
import numpy as np


img = cv2.imread('01.jpg',0)
kernel = np.ones((5,5),np.uint8)
dict = cv2.dilate(img,kernel,iterations = 1)
cv2.imshow("org",img)
cv2.imshow("result", dict)
cv2.waitKey(0)
cv2.destroyAllWindows()

我们定义了一个5*5的矩形卷积核,效果:

image.png

事实上,在某些情况下,我们可能需要椭圆形/圆形的内核。因此,为此,OpenCV具有一个函数cv.getStructuringElement()。我们只需传递内核的形状和大小,即可获得所需的内核,函数原型:
    retval=cv.getStructuringElement(shape, ksize[, anchor])

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

矩形:MORPH_RECT;

交叉形:MORPH_CROSS;

椭圆形:MORPH_ELLIPSE;

image.png

第二和第三个参数分别是内核的尺寸以及锚点的位置。一般在调用erode以及dilate函数之前,先定义一个变量来获得。

getStructuringElement函数的返回值: 对于锚点的位置,有默认值Point-1,-1),表示锚点位于中心点。element形状唯一依赖锚点位置,其他情况下,锚点只是影响了形态学运算结果的偏移。

我们看一下代码:

import cv2
import numpy as np


img = cv2.imread('01.jpg',0)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
dict = cv2.dilate(img,kernel,iterations = 1)
cv2.imshow("org",img)
cv2.imshow("result", dict)
cv2.waitKey(0)
cv2.destroyAllWindows()

至于卷积核的形状我在这里选择了椭圆形,大家可以自己选择其他形状进行实验:

image.png

腐蚀

再来看一下腐蚀,膨胀和腐蚀是一对好友,是相反的一对操作,所以腐蚀就是求局部最小值的操作。我们一般都会把腐蚀和膨胀对应起来理解和学习。下文就可以看到,两者的函数原型也是基本上一样的。

image.png

我们来看一下函数原型:

cv2.erode(img,kernel,iterations)->dst

第一个参数:img指需要腐蚀的图

第二个参数:kernel指腐蚀操作的内核,默认是一个简单的3X3矩阵,我们也可以利用getStructuringElement()函数指明它的形状

第三个参数:iterations指的是腐蚀次数,省略是默认为1

dst则为返回的图像。

代码:

import cv2
import numpy as np


img = cv2.imread('01.jpg',0)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
erode = cv2.erode(img,kernel,iterations = 1)
cv2.imshow("org",img)
cv2.imshow("result", erode)
cv2.waitKey(0)
cv2.destroyAllWindows()

效果:

image.png

腐蚀与膨胀是形态学处理中的基础操作,它们有着很重要的作用,也是后面开操作与闭操作的基础,所以必须熟练运用。


对计算机视觉感兴趣?这个社区推荐给你~

>>点击了解OpenVINO生态开发社区



高工
2020-06-29 21:47:10     打赏
2楼

感谢你的分享


工程师
2020-06-29 23:14:28     打赏
3楼

学到了


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]