Opencv3基础操作3——图像形态学处理


文章目录

    • 形态学腐蚀操作
    • 形态学膨胀操作
    • 开运算
    • 闭运算
    • 梯度运算
    • 礼帽
    • 黑帽

形态学腐蚀操作 腐蚀操作通常处理只有二值的图像(比如黑白),这里的例子就是一个值为255(白色),一个是1(黑色)。
先导入必要的库:
import cv2 #opencv读取的格式是BGR import numpy as np import matplotlib.pyplot as plt#Matplotlib是RGB

导入图像:
img = cv2.imread('dige.png')cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()

来看一下事例图:
Opencv3基础操作3——图像形态学处理
文章图片

可以看到,这两个字有很多“毛刺”,如何去掉呢,就是用腐蚀操作(腐蚀操作可以理解为减肥)。下面我们看看腐蚀操作的代码和执行腐蚀操作后图像的样子。
kernel = np.ones((3,3),np.uint8) erosion = cv2.erode(img,kernel,iterations = 1)#第一个参数是导入的图片,第二个参数是filter过滤器,第三个参数是迭代次数,即执行几次腐蚀操作cv2.imshow('erosion', erosion) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

可以发现毛刺被去掉了,并且字的笔画变细了。下面我们解释一下原理。
我们先倒入一张圆:
pie = cv2.imread('pie.png')cv2.imshow('pie', pie) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

腐蚀原理是这样的,我们先选择一个filter,这里我们选择全为1(其实这个过滤器的值并不需要特别考虑,暂时认为是1即可)的33矩阵,然后当我们检测到边缘点的时候,比如下图中的蓝色点,在这个33的过滤器中,含有黑色区域,那么这个点就会被腐蚀掉,变成黑色。
Opencv3基础操作3——图像形态学处理
文章图片

当如果这几个小方格都是白色,则这个点就不会变,比如下面的绿色点。
Opencv3基础操作3——图像形态学处理
文章图片

然后腐完就可以得到下面这张图(红色区域代表被腐蚀了的面积):
Opencv3基础操作3——图像形态学处理
文章图片

我们引入代码,看看多迭代几次的效果:
kernel = np.ones((30,30),np.uint8) erosion_1 = cv2.erode(pie,kernel,iterations = 1) erosion_2 = cv2.erode(pie,kernel,iterations = 2) erosion_3 = cv2.erode(pie,kernel,iterations = 3) res = np.hstack((erosion_1,erosion_2,erosion_3)) cv2.imshow('res', res) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

随着迭代的增加,可见白色区域越来越小。
腐蚀程度还跟过滤器的大小有关,如果过滤器越大,那么腐蚀的可能性就越大,过滤器越小,腐蚀的可能性就越小,对照腐蚀原理,读者应该可以快速想出原因。
形态学膨胀操作 膨胀操作就相当于腐蚀操作的逆操作(增肥)。
导入图像:
img = cv2.imread('dige.png')cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()

此图像还是上面拿着图:
Opencv3基础操作3——图像形态学处理
文章图片

我们先做腐蚀操作,去掉“毛边”:
kernel = np.ones((3,3),np.uint8) dige_erosion = cv2.erode(img,kernel,iterations = 1)cv2.imshow('erosion', erosion) cv2.waitKey(0) cv2.destroyAllWindows()

Opencv3基础操作3——图像形态学处理
文章图片

就像前面所说的,腐蚀操作不仅去掉了“毛刺”,还使笔画变细了,我们可以使用膨胀操作,把它变回来:
kernel = np.ones((3,3),np.uint8) dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)cv2.imshow('dilate', dige_dilate) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

他的膨胀原理也是一样,比如这个黄色的点,当这些小格子中有白色的点,那么我就变成白色。
Opencv3基础操作3——图像形态学处理
文章图片

我们看一下多迭代几次的效果:
pie = cv2.imread('pie.png')kernel = np.ones((30,30),np.uint8) dilate_1 = cv2.dilate(pie,kernel,iterations = 1) dilate_2 = cv2.dilate(pie,kernel,iterations = 2) dilate_3 = cv2.dilate(pie,kernel,iterations = 3) res = np.hstack((dilate_1,dilate_2,dilate_3)) cv2.imshow('res', res) cv2.waitKey(0) cv2.destroyAllWindows()

【Opencv3基础操作3——图像形态学处理】运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

开运算 开运算相当于把腐蚀和膨胀联系在一起,先腐蚀,再膨胀。
# 开:先腐蚀,再膨胀 img = cv2.imread('dige.png')kernel = np.ones((5,5),np.uint8) opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)#cv2.MORPH_OPEN为开运算cv2.imshow('opening', opening) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

闭运算 闭运算为开操作的逆运算,先膨胀,再腐蚀。
# 闭:先膨胀,再腐蚀 img = cv2.imread('dige.png')kernel = np.ones((5,5),np.uint8) closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)cv2.imshow('closing', closing) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

闭运算操作不会把“毛刺”去掉。
梯度运算 梯度运算就是膨胀-腐蚀得到的边界面积信息,我们直接来看例子。
先对图像进行膨胀和腐蚀操作:
# 梯度=膨胀-腐蚀 pie = cv2.imread('pie.png') kernel = np.ones((7,7),np.uint8) dilate = cv2.dilate(pie,kernel,iterations = 5) erosion = cv2.erode(pie,kernel,iterations = 5)res = np.hstack((dilate,erosion))cv2.imshow('res', res) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

然后进行梯度操作:
gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel) #cv2.MORPH_GRADIENT为梯度运算 cv2.imshow('gradient', gradient) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

礼帽 礼帽 = 原始输入-开运算结果。
按照上面的例子,开运算后不带“毛刺”了,礼帽运算后,就只剩下“毛刺”了。
#礼帽 img = cv2.imread('dige.png') tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)#cv2.MORPH_TOPHAT礼帽 cv2.imshow('tophat', tophat) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

黑帽 黑帽 = 闭运算-原始输入。
按上面的例子,闭运算后边界可能比原图膨胀一点点,那么减去原始图像,可能就只剩下一点点边界。
#黑帽 img = cv2.imread('dige.png') blackhat= cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)#cv2.MORPH_BLACKHAT黑帽 cv2.imshow('blackhat ', blackhat ) cv2.waitKey(0) cv2.destroyAllWindows()

运行结果:
Opencv3基础操作3——图像形态学处理
文章图片

    推荐阅读