OpenCV-Python -- Morphological Transformations

学习目标

  • 学习不同类型的形态学操作,比如腐蚀(Erosion),膨胀(Dilation),开操作(Opening),闭操作(Closing)等
  • 学习不同的函数,比如,cv2.erode()cv2.dilate()cv2.morphologyEx()

理论知识

形态学变换是一系列基于图像形状的简单操作。通常处理二值图像,输入有2个参数,1.输入图像;2.结构化元素或核,形状决定该操作的性质。两个基本的形态学操作为腐蚀膨胀。他们的变体,比如开操作,闭操作,梯度等。我们将使用下面的图像一一介绍形态学操作。

在这里插入图片描述

1. Erosion(腐蚀操作)

腐蚀的基本概念类似与土壤腐蚀,通常腐蚀前景的边界。操作过程:定义的核在图像上滑动,图像当前位置的像素为0或者1,只有核内所有的像素都为1,当前像素位置的值为1,否则就是0.
所以,根据核的大小,边界附近的像素为0。所以腐蚀操作相当于是将目标的边界变细。因此适合去除小的白色噪声。函数使用如下:

dst = cv2.erode(src, kernel, iterations) 
def erode(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None): 
    """
       @brief Erodes an image by using a specific structuring 		 
       element(结构化元素,比如卷积核).
       The function supports the in-place mode. Erosion can be 
       applied several ( iterations ) times. In case of multi-
       channel images, each channel is processed independently.
       
       @param src input image; the number of channels can be 
       arbitrary, but the depth should be one of CV_8U, CV_16U, 
       CV_16S, CV_32F or CV_64F.
       
       @param dst output image of the same size and type as src.
	   
	   @param kernel structuring element used for erosion; if 
	   `element=Mat()`, a `3 x 3` rectangular structuring element is 
	   used. Kernel can be created using #getStructuringElement.
       
       @param anchor position of the anchor within the element; 
       default value (-1, -1) means that the anchor is at the 
       element center.
       
       @param iterations number of times erosion is applied.可以对图像	
       使用多次腐蚀操作.
       
       @param borderType pixel extrapolation method, see 
       #BorderTypes
       
       @param borderValue border value in case of a constant border
       @sa  dilate, morphologyEx, getStructuringElement
    """

下面的例子:


class Morphological:
    def __init__(self, image):
        self.img = cv2.imread(image, 0)
        self.kernel = np.ones((5, 5), np.uint8)
        self.kernel_tophat = np.ones((9, 9), np.uint8)


    def erosion(self):
        erosion = cv2.erode(self.img, self.kernel, iterations=1)
        return erosion
    
    def dilate(self):
        dilation = cv2.dilate(self.img, self.kernel, iterations=1)
        return dilation
    
    def opening(self):
        opening = cv2.morphologyEx(self.img, cv2.MORPH_OPEN, self.kernel)
        return opening
	
	def closing(self):
        closing = cv2.morphologyEx(self.img, cv2.MORPH_CLOSE, self.kernel)
        return closing
    
    def morphological_gradient(self):
        gradient = cv2.morphologyEx(self.img, cv2.MORPH_GRADIENT, self.kernel)
        return gradient
    
    def top_hat(self):
        tophat = cv2.morphologyEx(self.img, cv2.MORPH_TOPHAT, self.kernel_tophat)
        return tophat
    
    def black_hat(self):
        blackhat = cv2.morphologyEx(self.img, cv2.MORPH_BLACKHAT, self.kernel)
        return blackhat
    
    def show(self, name, result):
        cv2.imshow('origin', self.img)
        cv2.imshow(name, result)
        cv2.waitKey(0)


if __name__ == '__main__':
    image = 'j.png'  # j_1.png
    mor = Morphological(image)
    # result1 = mor.erosion()
    # result1 = mor.dilate()
    # result1 = mor.opening()
    # result1 = mor.closing()
    # result1 = mor.morphological_gradient()
    # result1 = mor.top_hat()
    result1 = mor.black_hat()
    mor.show('black_hat', result1)

结果如下:
在这里插入图片描述

2. Dilation(膨胀)

相当于腐蚀的反操作,只要图像的至少一个非零元素在核内,那么该位置的像素值置1。通常会增粗边界。一般情况下,在去除噪声时,会先腐蚀后膨胀:腐蚀将白色噪声去除,但是会边界变细,那么膨胀可以补边界。

dilation = cv2.dilate(img,kernel,iterations = 1)
def dilate(src, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None):
    """
       @brief Dilates an image by using a specific structuring 	
       element.
       The function supports the in-place mode. Dilation can be 
       applied several ( iterations ) times. In case of multi-
       channel images, each channel is processed independently.
  
       @param src input image; the number of channels can be 
       arbitrary, but the depth should be one of CV_8U, CV_16U, 
       CV_16S, CV_32F or CV_64F.
       @param dst output image of the same size and type as src.
       @param kernel structuring element used for dilation; if 
       elemenat=Mat(), a 3 x 3 rectangular structuring element is 
       used. Kernel can be created using #getStructuringElement
       @param anchor position of the anchor within the element; 
       default value (-1, -1) means that the anchor is at the 
       element center.
       @param iterations number of times dilation is applied.
       @param borderType pixel extrapolation method, see 
       #BorderTypes
       @param borderValue border value in case of a constant border
       @sa  erode, morphologyEx, getStructuringElement
    """

示例代码见上述的使用,运行结果如下:
在这里插入图片描述

3. Opening

开操作:腐蚀+膨胀的连续处理。常用在去除噪声,下面介绍函数的使用:

cv2.morphologyEx(src, op, kernel)

上面的op主要包括下面的类型:

"""
	enum MorphTypes{
	    MORPH_ERODE    = 0, //腐蚀
	    MORPH_DILATE   = 1, //膨胀
	    MORPH_OPEN     = 2, //开操作
	    MORPH_CLOSE    = 3, //闭操作
	    MORPH_GRADIENT = 4, //梯度操作
	    MORPH_TOPHAT   = 5, //顶帽操作
	    MORPH_BLACKHAT = 6, //黑帽操作
	    MORPH_HITMISS  = 7  
	};
"""
def morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None): 
    """
       @brief Performs advanced morphological transformations.
      
       @param src Source image. The number of channels can be 
       arbitrary. The depth should be one of CV_8U, CV_16U, CV_16S, 
       CV_32F or CV_64F.
       @param dst Destination image of the same size and type as 
       source image.
       @param op Type of a morphological operation, see #MorphTypes
       @param kernel Structuring element. It can be created using 
       #getStructuringElement.
       @param anchor Anchor position with the kernel. Negative 
       values mean that the anchor is at the kernel center.
       @param iterations Number of times erosion and dilation are 
       applied.
       @param borderType Pixel extrapolation method, see 
       #BorderTypes
       @param borderValue Border value in case of a constant 
       border. The default value has a special meaning.
       
       当iteration大于1时,注意下面的操作顺序:
       @note The number of iterations is the number of times 
       erosion or dilatation operation will be applied.
       
       For instance, an opening operation (#MORPH_OPEN) with two 
       iterations is equivalent to apply
       successively: erode -> erode -> dilate -> dilate (and not 
       erode -> dilate -> erode -> dilate).
    """

示例代码见上述的使用,运行结果如下:
在这里插入图片描述

4. Closing

闭操作是开操作的逆过程:膨胀+腐蚀。常用于去除前景目标里面的小洞,或者目标里面小的黑色点。
代码在上面,运行结果如下:

在这里插入图片描述

5. Morphological Gradient(形态学梯度)

具体操作如下:梯度 = 膨胀-腐蚀,结果类似于得到目标的外轮廓。
运行结果如下:

在这里插入图片描述

6. Top Hat(顶帽操作)

顶帽 = Img - Opening,输入图像与开操作的差。
代码如上,核的大小为9x9,运行结果如下:
在这里插入图片描述

7. Black Hat(黑帽)

黑帽 = 闭运算-原始输入。
在这里插入图片描述

Structuring Element(结构化元素)

在上面的例子中,我们可以通过Numpy手动创建结构化元素,它是矩形。但是在一些情况下,我们需要特定形状的核。鉴于此,OpenCV提供了函数,具体的定义和使用如下:

cv2.getStructuringElement(shape, ksize, anchor=None)
"""
	@brief: 生成特定形状的核或着结构化元素
	@shape:结构化元素的形状
		矩形:MORPH_RECT = 0
		交叉形::MORPH_CROSS = 1
		椭圆形::MORPH_ELLIPSE = 2
	@ksize:核的大小
"""
    # Rectangular Kernel
    a = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

    # Elliptical Kernel
    b = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
    
    # Cross-shaped Kernel
    c = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
    print(a)
    print('=============')
    print(b)
    print('=============')
    print(c)
    print('=============')

输出如下:

[[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]]
=============
[[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]]
=============
[[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]]
=============
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值