参考文献
版权声明:本文的函数介绍和实现步骤参照 CSDN博主「SongpingWang」的原创文章 实现,最后用matplotlib对比图像。
链接:OpenCV—python 形态学处理(腐蚀、膨胀、开闭运算、边缘检测)
感谢作者!
引入
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
二值化图像
# 二值化
def threshold_demo(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
# cv2.threshold第二个参数设定 红色通道阈值(阈值影响开闭运算效果)
print("threshold value %s" % ret)
# 显示
# cv2.imshow("global_threshold_binary", binary)
return binary
膨胀、腐蚀
原来用cv2.imshow显示,现在用pyplot 把它们显示在一个窗口,方便对比。
img = cv2.imread('img/lena.png')
# 对图像二值化处理
img = threshold_demo(img)
# OpenCV定义的结构矩形元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# 腐蚀图像
eroded = cv2.erode(img, kernel)
# 膨胀图像
dilated = cv2.dilate(img, kernel)
# cv2.imshow("img", img)
# cv2.imshow("Eroded", eroded)
# cv2.imshow("Dilated", dilated)
# cv2.waitKey(0)
plt.subplot(131), plt.imshow(img,'gray') ,plt.title("原图")
plt.subplot(132), plt.imshow(dilated,'gray'), plt.title("膨胀")
plt.subplot(133), plt.imshow(eroded,'gray'), plt.title("腐蚀")
plt.show()
开运算、闭运算
# 闭运算 迭代次数不同
closed1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=1)
closed3 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=3)
closed5 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=5)
# 开运算
opened1 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=1)
opened3 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=3)
opened5 = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel, iterations=5)
# 梯度
# gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
# 显示如下腐蚀后的图像
# cv2.imshow("Close1", closed1)
# cv2.imshow("Close3", closed3)
# cv2.imshow("Open1", opened1)
# cv2.imshow("Open3", opened3)
# cv2.imshow("gradient", gradient)
# cv2.waitKey(0)
plt.subplot(241), plt.imshow(img,'gray') ,plt.title("原图")
plt.subplot(242), plt.imshow(opened1,'gray'), plt.title("开运算iterations=1")
plt.subplot(243), plt.imshow(opened3,'gray'), plt.title("开运算iterations=3")
plt.subplot(244), plt.imshow(opened5,'gray'), plt.title("开运算iterations=5")
plt.subplot(246), plt.imshow(closed1,'gray'), plt.title("闭运算iterations=1")
plt.subplot(247), plt.imshow(closed3,'gray'), plt.title("闭运算iterations=3")
plt.subplot(248), plt.imshow(closed5,'gray'), plt.title("闭运算iterations=5")
plt.show()
提取边缘
# 将两幅图像相减获得边;cv2.absdiff参数:(膨胀后的图像,腐蚀后的图像)
absdiff_img = cv2.absdiff(dilated, eroded);
result = cv2.bitwise_not(absdiff_img);
# cv2.imshow("absdiff_img", absdiff_img)
# cv2.imshow("result", result)
# cv2.waitKey(0)
plt.subplot(131), plt.imshow(img,'gray') ,plt.title("原图")
plt.subplot(132), plt.imshow(absdiff_img,'gray'), plt.title("腐蚀、膨胀两幅图像相减")
plt.subplot(133), plt.imshow(result,'gray'), plt.title("提取边缘")
plt.show()