目录
一、环境
二、形态学原理
三、代码演示
一、环境
本文使用环境为:
- Windows10
- Python 3.9.17
- opencv-python 4.8.0.74
二、形态学原理
在图像处理中,腐蚀和膨胀是两种基本的形态学操作,它们可以有效地用于图像的噪声减少、形状分析和图像增强等任务。OpenCV(Open Source Computer Vision Library)是一个广泛使用的开源计算机视觉库,提供了丰富的图像处理和分析函数,其中包括腐蚀和膨胀的操作。
腐蚀操作是一种形态学操作,它通过将图像中的每个像素替换为邻域像素的最小值,从而达到消除图像中的较小细节和降低图像噪声的效果。在OpenCV中,可以使用erode
函数实现腐蚀操作。该函数接受一个输入图像、一个核(结构元素)和指定的参数,返回腐蚀后的图像。
腐蚀操作的过程如下:对于输入图像中的每个像素,使用核在其邻域内进行遍历,并将最小值赋给该像素。这个过程可以在整个图像中重复进行,直到达到指定的迭代次数。腐蚀操作可以有效地消除图像中的较小细节和降低噪声,但同时也可能会使图像中的较大细节变小或消失。
膨胀操作是腐蚀操作的逆操作,它通过将图像中的每个像素替换为邻域像素的最大值,从而达到扩大图像中的较大细节和增强图像边缘的效果。在OpenCV中,可以使用dilate
函数实现膨胀操作。该函数同样接受一个输入图像、一个核和指定的参数,返回膨胀后的图像。
膨胀操作的过程与腐蚀操作相反:对于输入图像中的每个像素,使用核在其邻域内进行遍历,并将最大值赋给该像素。这个过程可以在整个图像中重复进行,直到达到指定的迭代次数。膨胀操作可以有效地扩大图像中的较大细节和增强图像边缘,但同时也可能会使图像中的较小细节消失或增大。
腐蚀和膨胀操作在计算机视觉和图像处理领域有着广泛的应用。例如,它们可以用于图像的噪声减少、边缘检测、形状分析和特征提取等任务。通过结合腐蚀和膨胀操作,还可以实现图像的开运算(先腐蚀后膨胀)和闭运算(先膨胀后腐蚀),它们可以用于去除图像中的小洞、填充孔洞以及平滑边缘等任务。
在使用OpenCV进行腐蚀和膨胀操作时,可以根据具体的需求选择不同的核和参数,以达到最佳的处理效果。同时,OpenCV还提供了许多其他的形态学操作函数,例如形态学梯度、顶帽、黑帽等,它们可以进一步扩展腐蚀和膨胀操作的应用范围。
总之,OpenCV提供的腐蚀和膨胀操作是计算机视觉和图像处理领域中非常基础和重要的技术之一。通过熟练掌握这些技术,可以有效地对图像进行处理和分析,提取出有用的特征信息,实现各种不同的计算机视觉任务。
三、代码演示
完整代码:
from __future__ import print_function
import cv2 as cv
import numpy as np
import argparse
src = None
erosion_size = 0
max_elem = 2
max_kernel_size = 21
title_trackbar_element_shape = 'Element:\n 0: Rect \n 1: Cross \n 2: Ellipse'
title_trackbar_kernel_size = 'Kernel size:\n 2n +1'
title_erosion_window = 'Erosion Demo'
title_dilation_window = 'Dilation Demo'
def main(image):
global src
src = cv.imread(cv.samples.findFile(image))
if src is None:
print('Could not open or find the image: ', image)
exit(0)
cv.namedWindow(title_erosion_window)
cv.createTrackbar(title_trackbar_element_shape, title_erosion_window, 0, max_elem, erosion)
cv.createTrackbar(title_trackbar_kernel_size, title_erosion_window, 0, max_kernel_size, erosion)
cv.namedWindow(title_dilation_window)
cv.createTrackbar(title_trackbar_element_shape, title_dilation_window, 0, max_elem, dilatation)
cv.createTrackbar(title_trackbar_kernel_size, title_dilation_window, 0, max_kernel_size, dilatation)
erosion(0)
dilatation(0)
cv.waitKey()
# 选择结构算子
def morph_shape(val):
if val == 0:
return cv.MORPH_RECT # 矩形
elif val == 1:
return cv.MORPH_CROSS # X形
elif val == 2:
return cv.MORPH_ELLIPSE # 椭圆
def erosion(val):
# 结构算子半径
erosion_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_erosion_window)
# 结构算子形状
erosion_shape = morph_shape(cv.getTrackbarPos(title_trackbar_element_shape, title_erosion_window))
## 结构算子
element = cv.getStructuringElement(erosion_shape, (2 * erosion_size + 1, 2 * erosion_size + 1),
(erosion_size, erosion_size))
## 腐蚀图像
erosion_dst = cv.erode(src, element)
cv.imshow(title_erosion_window, erosion_dst)
def dilatation(val):
# 结构算子半径
dilatation_size = cv.getTrackbarPos(title_trackbar_kernel_size, title_dilation_window)
# 结构算子形状
dilation_shape = morph_shape(cv.getTrackbarPos(title_trackbar_element_shape, title_dilation_window))
## 结构算子
element = cv.getStructuringElement(dilation_shape, (2 * dilatation_size + 1, 2 * dilatation_size + 1),
(dilatation_size, dilatation_size))
## 膨胀图像
dilatation_dst = cv.dilate(src, element)
cv.imshow(title_dilation_window, dilatation_dst)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Code for Eroding and Dilating tutorial.')
parser.add_argument('--input', help='Path to input image.', default='data/LinuxLogo.jpg') # 输入图像路径
args = parser.parse_args()
main(args.input)