opencv图像处理之形态学转换

1.腐蚀、膨胀、梯度

形态学操作: 根据图像形状进行的简单操作。一般情况下对二值化图像进行的操作。

腐蚀: 就像土壤侵蚀一样,这个操作会把前景物体的边界腐蚀掉(但是前景仍然是白色)。这是怎么做到的呢?卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是1,那么中心元素就保持原来的像素值,否则就变为零。这对于去除白噪声很有用,也可以用来断开两个连在一块的物体等。

膨胀: 与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是1,中心元素的像素值就是1。所以这个操作会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。

梯度: 其实就是一幅图像膨胀与腐蚀的差别。结果看上去就像前景物体的轮廓。


代码速记:

  • cv2.erode()
  • cv2.dilate()
  • cv2.morphologyEx():cv2.MORPH_GRADIENT

参数解释:

cv2.erode(raw_binary,kernel,iterations=1)#原图像、卷积核、迭代次数
cv2.dilate(raw_binary,kernel,iterations=1)#原图像、卷积核、迭代次数
cv2.morphologyEx(raw_binary,cv2.MORPH_GRADIENT,kernel)#原图像、运算方式、卷积核

实战:

def erode_dilate(self):
	#【1】转二值图像
    raw_gray=cv2.imread(self.infile,0)
    ret, raw_binary = cv2.threshold(raw_gray, 230, 255, cv2.THRESH_BINARY_INV)#230以下的变白
    #【2】运算
    kernel=np.ones((5,5),np.uint8)
    erosion=cv2.erode(raw_binary,kernel,iterations=1)#腐蚀
    dilation=cv2.dilate(raw_binary,kernel,iterations=1)#膨胀
    gradient=cv2.morphologyEx(raw_binary,cv2.MORPH_GRADIENT,kernel)#梯度:膨胀-腐蚀
    #【3】画图
    titles=['raw','erosion','dilation','gradient']
    images=[raw_binary,erosion,dilation,gradient]
    for i in range(4):
        plt.subplot(1,4,i+1),plt.imshow(images[i],'gray')
        plt.title(titles[i])
        plt.xticks([]),plt.yticks([])
    plt.show()

在这里插入图片描述

2.开运算、闭运算、礼帽、黑帽

开运算: 先腐蚀再进行膨胀就叫做开运算。就像我们上面介绍的那样,它被用来去除噪声。

闭运算: 先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点。

礼帽: 原始图像与进行开运算之后得到的图像的差。

黑帽: 原始图像与进行闭运算之后得到的图像的差。


代码速记:

  • cv2.morphologyEx():cv2.MORPH_CLOSE
  • cv2.morphologyEx():cv2.MORPH_OPEN
  • cv2.morphologyEx():cv2.MORPH_TOPHAT
  • cv2.morphologyEx():cv2.MORPH_BLACKHAT

实战:

def open_close_hat(self):
	#【1】转二值图像
    inner_gray=cv2.imread('../images/i_inner.jpg',0)
    ret, inner_binnary = cv2.threshold(inner_gray, 230, 255, cv2.THRESH_BINARY_INV)#230以下的变白
    outer_gray=cv2.imread('../images/i_outer.jpg',0)
    ret, outer_binary = cv2.threshold(outer_gray, 230, 255, cv2.THRESH_BINARY_INV)#230以下的变白  
    #【2】运算
    kernel=np.ones((5,5),np.uint8)  
    closing=cv2.morphologyEx(inner_binnary,cv2.MORPH_CLOSE,kernel)#闭运算,先膨胀再腐蚀,去小孔
    opening=cv2.morphologyEx(outer_binary,cv2.MORPH_OPEN,kernel)#开运算,先腐蚀再膨胀,去噪声
    tophat=cv2.morphologyEx(outer_binary,cv2.MORPH_TOPHAT,kernel)#礼帽:开运算-原图
    blackhat=cv2.morphologyEx(inner_binnary,cv2.MORPH_BLACKHAT,kernel)#黑帽:闭运算-原图
    #【3】画图    
    titles=['inner','closing','blackhat','outer','opening','tophat']
    images=[inner_binnary,closing,blackhat,outer_binary,opening,tophat]
    for i in range(6):
        plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
        plt.title(titles[i])
        plt.xticks([]),plt.yticks([])
    plt.show()

在这里插入图片描述

3.创建不同形状的核

  • cv2.getStructuringElement()

正方形:

print(cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)))
#[[1 1 1 1 1]
# [1 1 1 1 1]
# [1 1 1 1 1]
# [1 1 1 1 1]
# [1 1 1 1 1]]

圆形/椭圆:

print(cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)))
#[[0 0 1 0 0]
# [1 1 1 1 1]
# [1 1 1 1 1]
# [1 1 1 1 1]
# [0 0 1 0 0]]

十字:

print(cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)))
#[[0 0 1 0 0]
# [0 0 1 0 0]
# [1 1 1 1 1]
# [0 0 1 0 0]
# [0 0 1 0 0]]
发布了154 篇原创文章 · 获赞 45 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_36622009/article/details/104571272