Python+OpenCV之形态学操作详解

1. 形态学操作的概念

形态学操作是图像处理中一类基于形状的图像处理方法。其基本思想是将一些指定形状的结构元素(structuring element)在图像上移动,并与图像的一定区域进行匹配,从而实现一些特定的操作。在OpenCV中,形态学操作主要包括膨胀(dilate)、腐蚀(erode)、开运算(opening)、闭运算(closing)等操作。

1.1 结构元素的定义

结构元素可以看作是一些用来搜索的模板。其形状和大小都是可以定义的,常见的包括正方形、矩形、十字形、菱形、圆形等。在OpenCV中,可以使用cv2.getStructuringElement(elementShape, ksize)函数来创建结构元素。

# 创建一个3*3的十字形结构元素

import cv2

kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))

其中,elementShape参数可以选择的类型有如下五种:

cv2.MORPH_RECT:矩形结构

cv2.MORPH_CROSS:十字形结构

cv2.MORPH_ELLIPSE:椭圆形结构

cv2.MORPH_TOPHAT:顶帽操作的结构元素

cv2.MORPH_BLACKHAT:黑帽操作的结构元素

ksize参数则表示结构元素的大小,通常为一个二元组,其第一个元素为结构元素的行数,第二个元素为结构元素的列数。

1.2 操作的原理

在对图像进行形态学操作时,结构元素通过对其搜索区域的每个像素点进行匹配来决定该像素点的最终结果。操作的原理如下:

膨胀:将结构元素移动到每个像素点处,并将其周围一定区域的像素值与结构元素进行比较,取其中最大值作为该像素点的新值(即使图像中的亮区域更加连通)。

腐蚀:同膨胀操作,不同之处在于取的是比较区域中的最小值作为该像素点的新值(相当于让图像中的暗区域更加连通)。

开运算:先腐蚀,再膨胀。

闭运算:先膨胀,再腐蚀。

2. 形态学操作的应用

形态学操作在图像处理中的应用非常广泛,其中包括二值化、轮廓提取、去噪声等方面。下面以二值化和轮廓提取为例进行介绍。

2.1 二值化处理

在图像二值化时,可以通过形态学操作来增加图像的连通性和减小噪声的影响。一般来说,可以先使用开运算来去除黑噪声,再使用闭运算来去除白噪声。

import cv2

img = cv2.imread("test.jpg", 0)

# 创建结构元素

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# 进行开运算操作

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

# 进行闭运算操作

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

在代码中,cv2.imread()函数用于读取一张灰度图像;getStructuringElement()函数用于创建一个3*3的矩形结构元素;morphologyEx()函数用于进行开运算和闭运算操作。

2.2 轮廓提取

形态学操作可以用来增加图像的连通性,从而有助于轮廓的提取。

import cv2

img = cv2.imread("test.jpg", 0)

# 创建结构元素

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# 进行膨胀操作

dilation = cv2.dilate(img, kernel)

# 轮廓提取

contours, hierarchy = cv2.findContours(

dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

在代码中,dilate()函数用于进行膨胀操作;findContours()函数用于提取图像的轮廓。

2.3 代码示例

import cv2

img = cv2.imread("test.jpg", 0)

# 创建结构元素

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# 进行开运算操作

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

# 进行闭运算操作

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

# 进行膨胀操作

dilation = cv2.dilate(closing, kernel)

# 轮廓提取

contours, hierarchy = cv2.findContours(

dilation, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

# 绘制轮廓

cv2.drawContours(img, contours, -1, (0, 255, 0), 2)

cv2.imshow("result", img)

cv2.waitKey()

cv2.destroyAllWindows()

以上代码实现了对一张灰度图像的开运算、闭运算、膨胀和轮廓提取等操作,并在原图中标记出了图像的轮廓。

后端开发标签