Python+OpenCV之形态学的操作方法是什么

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库可以方便地进行形态学操作。本文简单介绍了形态学操作中的基本概念,包括结构元素、膨胀、腐蚀、开运算和闭运算。最后,我们结合一个实例,演示了如何利用形态学操作进行图像预处理。

后端开发标签