12.1 开运算与闭运算
开运算和闭运算就是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的,即先开后闭并不能得到原先的图像。
- 开运算:先腐蚀,再膨胀。能够排除小黑点。
- 闭运算:先膨胀,再腐蚀。能够排除小亮点。
但这两者并不是可逆的,即先开后闭并不能得到原先的图像。
12.2 形态学梯度
梯度 = 膨胀 – 腐蚀
因为膨胀是对图像的高亮区进行扩展,腐蚀是对图像的高亮区进行收缩,两者相减便能得到图像的轮廓。
12.3 礼帽和黑帽
礼帽 = 原图 - 开运算
黑帽 = 闭运算 – 原图
12.4 cv2.morphologyEx()形态学函数
函数原型
cv2. morphologyEx(src,op,kernel,dst = None,anchor = None,iterations = None,borderType = None,borderValue = None)
参数
- src:输入图像,输入图像的通道数是任意的。
- op:形态操作的类型如:cv2.MORPH_ERODE(腐蚀)= erode(src,element);cv2.MORPH_DILATE(膨胀)= dilate(src,element);cv2.MORPH_OPEN(开运算)= open(src,element)=dilate(erode(src,element));cv2.MORPH_CLOSE(闭运算)= close(src,element)=erode(dilate(src,element));cv2.MORPH_GRADIENT(梯度)=dilate(src,element)−erode(src,element);cv2.MORPH_TOPHAT(“礼帽”)=src−open(src,element);cv2.MORPH_BLACKHAT(黑帽)=close(src,element)−src;cv2.MORPH_HITMISS(命中或错过)-仅支持CV_8UC1二进制图像。可以在文档中找到相关教程)(详细参考官方文档 MorphTypes)
- kernel:输入一个数组作为核。能被getStructuringElement创建。
- anchor:核的锚点位置,负值说明该锚点位于核中心。默认为核中心。
- iterations:整型int。腐蚀与膨胀被应用的次数。默认为None。例:一次开运算迭代两次:(MORPH_OPEN=
)伴随两次迭代等于:腐蚀--腐蚀--膨胀--膨胀。
- borderType:像素边界扩展类型,参照官方文档所列的几种类型BorderTypes
- borderValue:边界为常量时的边界值。默认值有特殊含义。默认值为None。
12.5 综合示例
import cv2
import numpy as np
import matplotlib.pyplot as plt
def erode_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
erode = cv2.morphologyEx(image, cv2.MORPH_ERODE, kernel)
return erode
def dilate_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
dilate = cv2.morphologyEx(image, cv2.MORPH_DILATE, kernel)
return dilate
def close_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
iClose = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
return iClose
def close_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
iClose = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
return iClose
def open_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
iOpen = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
return iOpen
def gradient_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
gdadient = cv2.morphologyEx(image,cv2.MORPH_GRADIENT, kernel)
return gdadient
def topHat_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
topHat = cv2.morphologyEx(image,cv2.MORPH_TOPHAT, kernel)
return topHat
def blackHat_opration(image):
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
blackHat = cv2.morphologyEx(image,cv2.MORPH_BLACKHAT, kernel)
return blackHat
img = cv2.imread("C:\\Users\\liyou\\Downloads\\picture1.jpeg")
##img = cv2.merge((img[:,:,2],img[:,:,1],img[:,:,0]))
gray = cv2.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
erode = erode_opration(binary)
dilate = dilate_opration(binary)
iOpen = open_opration(binary)
iClose = close_opration(binary)
gdadient = gradient_opration(binary)
topHat = topHat_opration(binary)
blackHat = blackHat_opration(binary)
names = ['Origin','gray','binary','erode','dilate','iOpen','iClose','gdadient','topHat','blackHat']
images = [img,gray,binary,erode,dilate,iOpen,iClose,gdadient,topHat,blackHat]
plt.figure(figsize=(25.6,12.8))
for i in range(3):
for j in range(4):
plt.subplot(3,4,i*4+j+1),plt.imshow(images[i*4+j])
plt.title(names[i*4+j],fontsize=30), plt.xticks([]), plt.yticks([])
num=i*4+j
if num >= len(names)-1:
break
plt.show()
运行结果如下: