Python-OpenCV中的图像处理-形态学转换

Python-OpenCV中的图像处理-形态学转换

形态学转换

  • 形态学操作:腐蚀,膨胀,开运算,闭运算,形态学梯度,礼帽,黑帽等
  • 主要涉及函数:cv2.erode(), cv2.dilate(), cv2.morphologyEx()
  • 原理:形态学操作是根据图像形状进行的简单操作。一般情况下对二值化图像进行的操作。需要输入两个参数,一个是原始图像,第二个被称为结构化元素或核,它是用来决定操作的性质的。两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算,梯度等。

腐蚀

就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉(但是前景仍然是白色)。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是 1,那么中心元素就保持原来的像素值,否则就变为零。这回产生什么影响呢?根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为 0),所以前景物体会变小,整幅图像的白色区域会减少。这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。

python 复制代码
import numpy as np
import cv2
from matplotlib import pyplot as plt


img = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Dilation.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((5,5), np.uint8)
erosion = cv2.erode(img, kernel=kernel, iterations=1)

plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(erosion, cv2.COLOR_BGR2RGB)), plt.title('erode'), plt.xticks([]), plt.yticks([])
plt.show()

膨胀

与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是 1,中心元素的像素值就是 1。所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。

python 复制代码
import numpy as np
import cv2
from matplotlib import pyplot as plt

# 膨胀
img = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Original_Image.png', cv2.IMREAD_GRAYSCALE)

kernel = np.ones((5,5), np.uint8)
dilation = cv2.dilate(img, kernel=kernel, iterations=1)

plt.subplot(121), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(cv2.cvtColor(dilation, cv2.COLOR_BGR2RGB)), plt.title('dilate'), plt.xticks([]), plt.yticks([])
plt.show()

开运算

先腐蚀再膨胀就叫做开运算。它被用来去除噪声。这里我们用到的函数是 cv2.morphologyEx()

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

闭运算

先膨胀再腐蚀就叫做闭运算。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

形态学梯度

其实就是一幅图像膨胀与腐蚀的差别,结果看上去就像前景物体的轮廓。

gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

礼帽

原始图像与进行开运算之后得到的图像的差。下面的例子是用一个 9x9 的核进行礼帽操作的结果。

tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

黑帽

进行闭运算之后得到的图像与原始图像的差

blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

形态学操作之间的关系

形态学转换

  • Opening:
    dst = open(src, element) = dilate(erode(src, element), element)
  • Closing:
    dst = close(src, element) = erode(dilate(src, element), element)
  • Morphological gradient:
    dst = morph_grad(src, element) = dilate(src, element) - erode(src, element)
  • "Top hat":
    dst = tophat(src, element) = src - open(src, element)
  • "Black hat":
    dst = blackhat(src, element) = close(src, element) - src

形态学代码例程

python 复制代码
import numpy as np
import cv2
from matplotlib import pyplot as plt

'''
形态学转换
Opening: 
    dst = open(src, element) = dilate(erode(src, element), element)

Closing:
    dst = close(src, element) = erode(dilate(src, element), element)

Morphological gradient:
    dst = morph_grad(src, element) = dilate(src, element) - erode(src, element)

"Top hat":
    dst = tophat(src, element) = src - open(src, element)

"Black hat":
    dst = blackhat(src, element) = close(src, element) - src
'''

# 开运算
# 先进行腐蚀在进行膨胀叫做开运算。用来去除噪音
# opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

# 闭运算
# 先进行膨胀再进行腐蚀叫做闭运算。用来填充前景物体中的小洞,或者全景上的小黑点。
# closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

# 形态学梯度
# 就是一副图像膨胀与腐蚀的差别,结果看上去就像前景物体的轮廓。
# gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

# 礼帽
# 原始图像与进行开运算之后得到的图像的差
# tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

# 黑帽
# 原始图像与进行闭运算之后得到的图像的差
# blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

# 结构化元素
kernel_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))       # 矩形核
kernel_elli = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))    # 椭圆核
kernel_cros = cv2.getStructuringElement(cv2.MORPH_CROSS, (5,5))      # 十字核

# 卷积核
# kernel = kernel_rects
# kernel = kernel_elli
# kernel = kernel_cros
kernel = np.ones((5,5), np.uint8)
kernel9x9 = np.ones((15,15), np.uint8)

img_origin = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Dilation.png', cv2.IMREAD_COLOR)
img_gray = cv2.imread('./resource/opencv/image/Morphology_1_Tutorial_Theory_Dilation.png', cv2.IMREAD_GRAYSCALE)

# 开运算 腐蚀=>膨胀
opening = cv2.morphologyEx(img_gray, cv2.MORPH_OPEN, kernel)

# 闭运算 膨胀=>腐蚀
closing = cv2.morphologyEx(img_gray, cv2.MORPH_CLOSE, kernel)

# 梯度 膨胀-腐蚀 
gradient = cv2.morphologyEx(img_gray, cv2.MORPH_GRADIENT, kernel)

# 礼帽  原始图像与进行开运算之后得到的图像的差
tophat = cv2.morphologyEx(img_gray, cv2.MORPH_TOPHAT, kernel9x9)

# 黑帽 进行闭运算之后与原始图像的图像的差
blackhat = cv2.morphologyEx(img_gray, cv2.MORPH_BLACKHAT, kernel9x9)

# 腐蚀
erosion = cv2.erode(img_gray, kernel=kernel, iterations=1)

# 膨胀 
dilation = cv2.dilate(img_gray, kernel=kernel, iterations=1)

plt.subplot(331), plt.imshow(cv2.cvtColor(img_origin,cv2.COLOR_BGR2RGB), 'gray'), plt.title('origin'), plt.xticks([]), plt.yticks([])
plt.subplot(332), plt.imshow(img_gray, 'gray'), plt.title('gray'), plt.xticks([]), plt.yticks([])
plt.subplot(333), plt.imshow(opening, 'gray'), plt.title('open'), plt.xticks([]), plt.yticks([])
plt.subplot(334), plt.imshow(closing, 'gray'), plt.title('close'), plt.xticks([]), plt.yticks([])
plt.subplot(335), plt.imshow(gradient, 'gray'), plt.title('gradient'), plt.xticks([]), plt.yticks([])
plt.subplot(336), plt.imshow(tophat, 'gray'), plt.title('tophat'), plt.xticks([]), plt.yticks([])
plt.subplot(337), plt.imshow(blackhat, 'gray'), plt.title('blackhat'), plt.xticks([]), plt.yticks([])
plt.subplot(338), plt.imshow(erosion, 'gray'), plt.title('erode'), plt.xticks([]), plt.yticks([])
plt.subplot(339), plt.imshow(dilation, 'gray'), plt.title('dilate'), plt.xticks([]), plt.yticks([])
plt.show()
相关推荐
小爬虫程序猿7 分钟前
如何利用Python爬虫精准获取苏宁易购商品详情
开发语言·爬虫·python
API快乐传递者7 分钟前
Python爬虫获取1688详情接口详细解析
开发语言·爬虫·python
是娜个二叉树!14 分钟前
图像处理基础 | 查看两张图像的亮度差异,Y通道相减
图像处理·opencv·计算机视觉
古月居GYH15 分钟前
【计算机视觉】opencv-停车位检测原理及代码演示
人工智能·opencv·计算机视觉
Json_1817901448020 分钟前
拍立淘按图搜索API接口需要遵循一定的步骤和注意事项
大数据·python·api
CodeClimb23 分钟前
【华为OD-E卷-寻找密码 100分(python、java、c++、js、c)】
java·python·华为od
喵手41 分钟前
Java 实现日志文件大小限制及管理——以 Python Logging 为启示
java·开发语言·python
研一计算机小白一枚1 小时前
图像处理中的图像配准方法
图像处理·人工智能·计算机视觉
SchrodingerSDOG1 小时前
(补)算法刷题Day24: BM61 矩阵最长递增路径
数据结构·python·算法·矩阵