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

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

  • 形态学转换
    • 腐蚀
    • 膨胀
    • 开运算
    • 闭运算
    • 形态学梯度
    • 礼帽
    • 黑帽
    • 形态学操作之间的关系
  • 形态学代码例程

形态学转换

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

腐蚀

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

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

Python-OpenCV中的图像处理-形态学转换_第1张图片

膨胀

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

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

Python-OpenCV中的图像处理-形态学转换_第2张图片

开运算

先腐蚀再膨胀就叫做开运算。它被用来去除噪声。这里我们用到的函数是 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

形态学代码例程

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

Python-OpenCV中的图像处理-形态学转换_第3张图片

你可能感兴趣的:(python,opencv,图像处理)