1. 前言
形态学是图像处理中一种基础的方法,常用于图像分割、边缘检测、模板匹配等领域。在利用Python进行图像处理时,可以使用OpenCV库进行形态学操作。本文将介绍Python+OpenCV中的形态学操作方法。
2. 基础概念
2.1 结构元素
结构元素是形态学操作中的一个重要概念。它是一个小的、特定形状的图像,用于描述形态学算法中的模板。结构元素可以是任意形状,但通常使用矩形、椭圆或十字形等形状。
在OpenCV中,可以使用cv2.getStructuringElement()函数创建结构元素。该函数的第一个参数是结构元素的形状,可以是cv2.MORPH_RECT(矩形)、cv2.MORPH_ELLIPSE(椭圆)或cv2.MORPH_CROSS(十字形)。第二个参数是结构元素的大小。
import cv2
# 创建一个3x3的、十字形的结构元素
cross_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
print(cross_kernel)
# 输出:
# array([[0, 1, 0],
# [1, 1, 1],
# [0, 1, 0]], dtype=uint8)
2.2 膨胀和腐蚀
膨胀是形态学操作中的一种基础操作,其作用是增加物体的像素。膨胀操作可以使物体边界扩大、断开小的连接以及填充物体内部的空洞。
在OpenCV中,可以使用cv2.dilate()函数进行膨胀操作。该函数的第一个参数是要进行膨胀的图像,第二个参数是结构元素。
import cv2
import numpy as np
# 读取一张图片
img = cv2.imread('lena.jpg')
# 创建一个3x3的、十字形的结构元素
cross_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
# 对图像进行膨胀操作
dilated_img = cv2.dilate(img, cross_kernel)
# 将原图、膨胀后的图像拼接在一起显示
concat_img = np.concatenate((img, dilated_img), axis=1)
cv2.imshow('dilated', concat_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:结构元素的大小越大,膨胀后的效果越明显。
腐蚀是形态学操作中的另一种基础操作,其与膨胀操作相反,可以使物体边界收缩。腐蚀操作可以使物体边界变得更加光滑,可以断开物体之间的联系或去除孤立的小点。
在OpenCV中,可以使用cv2.erode()函数进行腐蚀操作。该函数的参数与cv2.dilate()函数相同。
import cv2
import numpy as np
# 读取一张图片
img = cv2.imread('lena.jpg')
# 创建一个3x3的、十字形的结构元素
cross_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
# 对图像进行腐蚀操作
eroded_img = cv2.erode(img, cross_kernel)
# 将原图、腐蚀后的图像拼接在一起显示
concat_img = np.concatenate((img, eroded_img), axis=1)
cv2.imshow('eroded', concat_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:结构元素的大小越大,腐蚀后的效果越明显。
2.3 开运算和闭运算
开运算和闭运算是形态学操作中的两种常见操作。它们分别由膨胀和腐蚀操作组成。开运算可以去除小的物体、平滑物体边界,而闭运算可以填充物体内部的空洞、连接相邻的物体。
在OpenCV中,可以使用cv2.morphologyEx()函数进行开运算和闭运算操作。该函数的第一个参数是要进行运算的图像,第二个参数是运算类型(cv2.MORPH_OPEN代表开运算,cv2.MORPH_CLOSE代表闭运算),第三个参数是结构元素。
import cv2
import numpy as np
# 读取一张图片
img = cv2.imread('lena.jpg')
# 创建一个3x3的、十字形的结构元素
cross_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (3, 3))
# 对图像进行开运算操作
opened_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, cross_kernel)
# 对图像进行闭运算操作
closed_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, cross_kernel)
# 将原图、开运算后的图像、闭运算后的图像拼接在一起显示
concat_img = np.concatenate((img, opened_img, closed_img), axis=1)
cv2.imshow('open and close', concat_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
注意:开运算和闭运算的效果受结构元素的大小与形状影响。
3. 实例展示
以下实例将结合前面介绍的形态学操作,实现对一张图像进行预处理,以便进行物体检测。我们将对原图像进行灰度化、二值化、开运算、膨胀等操作,得到一张预处理后的图像。
import cv2
import numpy as np
# 读取一张彩色图像
img = cv2.imread('object_detection.jpg')
# 将图像转换为灰度图像
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 对图像进行二值化处理
ret, binary_img = cv2.threshold(gray_img, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# 创建一个7x7的、十字形的结构元素
cross_kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (7, 7))
# 对二值化后的图像进行开运算操作
opened_img = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, cross_kernel)
# 对开运算后的图像进行膨胀操作
dilated_img = cv2.dilate(opened_img, cross_kernel)
# 显示预处理后的图像
cv2.imshow('preprocessed', dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
上述代码中,cv2.threshold()函数用于对图像进行二值化处理。其中,第一个参数为要处理的图像,第二个参数为阈值,第三个参数为最大值,第四个参数为阈值处理类型。在本例中,采用了自适应阈值处理方法(cv2.THRESH_OTSU)。这种方法可以根据图像直方图,自动计算二值化阈值。
预处理后的图像如下所示:
4. 总结
形态学是图像处理中常用的一种方法,可以用于图像分割、边缘检测、模板匹配等多个领域。Python中使用OpenCV库可以方便地进行形态学操作。本文简单介绍了形态学操作中的基本概念,包括结构元素、膨胀、腐蚀、开运算和闭运算。最后,我们结合一个实例,演示了如何利用形态学操作进行图像预处理。