Opencv中的开运算和闭运算操作讲解(python实现)

文章目录

  • 1.首先了解腐蚀和膨胀原理
  • 2.开运算
  • (1)为什么开运算可以去白噪点呢?
  • (2).函数讲解
  • (3)代码实战
  • 3.闭运算
  • (1)函数讲解
  • (2)代码实战
  • 1.首先了解腐蚀和膨胀原理

    https://mydreamambitious.blog.csdn.net/article/details/125265431


    2.开运算

    开运算=腐蚀+膨胀(顺序不可颠倒)

    (1)为什么开运算可以去白噪点呢?

    根据腐蚀的原理,使用一个给定大小的卷积核(结构单元)对图像进行卷积,操作是用卷积核(结构元素)B与其覆盖的二值图像A做“与”操作,如果结果为1,那么为1,否则为0;但是对于噪点的话,很多情况下在于卷积核进行与操作之后结果都为0,所以对于二值图像那么就是黑色,也就是白色的噪点变成黑色(相当于白色噪点被去掉)。腐蚀之后图像中的主要部分也会变小(“瘦”),所以需要使用膨胀进行还原;膨胀的过程是使用卷积核与二值图像进行或操作,只要其中有一个为1,则结果为1,否则结果为0.从而达到了去白噪点。
    比如下面一张图中,可以看到其中有很多的白色噪点,所以这个时候可以使用开运算操作。

    (2).函数讲解

    morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None):
    

    Src:输入的原始图像
    Op:进行操作(开运算或者闭运算)
    Kernel:卷积核的大小
    Dst:输出的图像
    Anchor:默认值为(-1,-1),卷积的中心
    Iterations:迭代的次数
    borderType:用于推断图像外部像素的某种边界模式。注意它有默认值 BORDER_DEFAULT
    borderValue:边界值(如果是常量边界)。默认morphologyDefaultBorderValue具有特殊含义。对于侵蚀,它被转换为+\inf;对于膨胀,它被转换为-\inf,这意味着只有在图像内部的像素上才能有效地计算最小值(最大值)

    (3)代码实战

    import os
    import cv2
    import random
    import numpy as np
    
    #产生白色噪点
    def ProduceWhiteNoise(img_path='images/Exen.png'):
        image=cv2.imread(img_path)
        h,w,c=np.shape(image)
        noise=np.zeros(shape=image.shape,dtype=np.uint8)
        # print(np.shape(image))
        #固定产生白噪点的个数
        count=0
        prob=0.95
        for i in range(h):
            for j in range(w):
                sand=random.random()
                if count<=50000 and sand>prob:
                    noise[i][j]=255
                    count+=1
                else:
                    noise[i][j]=image[i][j]
        cv2.imshow('image',noise)
        cv2.waitKey(0)
        cv2.imwrite('images/Exen_copy.png',noise)
    
    #进行开运算的方式一,直接调用开运算函数
    def MorphologyExAnd(img_path='images/Exen_copy.png'):
        #读取图片
        img_src=cv2.imread(img_path)
        img=cv2.resize(src=img_src,dsize=(500,500))
        #获取卷积核,这里使用矩阵的方式
        kernel=cv2.getStructuringElement(shape=cv2.MORPH_RECT,ksize=(7,7))
        #进行开运算
        img=cv2.morphologyEx(src=img,op=cv2.MORPH_OPEN,kernel=kernel,iterations=1)
        #显示图片
        cv2.imshow('img_src',img_src)
        cv2.imshow('img',img)
        #等待接收鼠标或者键值
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    #进行开运算方式2=腐蚀+膨胀
    def Erode_Dilate(img_path='images/Exen_copy.png'):
        #读取图像
        img_src=cv2.imread(img_path)
        img=cv2.resize(src=img_src,dsize=(500,500))
        #获取卷积核
        kernel=cv2.getStructuringElement(shape=cv2.MORPH_RECT,ksize=(7,7))
        #首先进行腐蚀操作
        img_erode=cv2.erode(src=img,kernel=kernel,iterations=2)
        #再进行膨胀操作
        img_dilate=cv2.dilate(src=img_erode,kernel=kernel,iterations=2)
        #显示图像
        cv2.imshow('img_src',img_src)
        cv2.imshow('img_dilate',img_dilate)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    
    if __name__ == '__main__':
        print('Pycharm')
        # ProduceWhiteNoise()
        # MorphologyExAnd()
        Erode_Dilate()
    
    

    直接调用开运算操作的结果

    使用:腐蚀+膨胀方式

    可以看到两者的效果都是很不错的。


    3.闭运算

    闭运算=膨胀+腐蚀
    (和开运算相反)
    达到的效果:
    比如下面一张图中,可以看到其中有很多的黑色噪点,所以这个时候可以使用开运算操作。

    (1)函数讲解

    和开运算一样的函数,只不过op的方式改为:cv2.MORPH_CLOSE

    (2)代码实战

    import os
    import cv2
    import random
    import numpy as np
    
    #产生黑色噪点
    def ProduceBlackNoise(img_path='images/Exen.png'):
        image=cv2.imread(img_path)
        h,w,c=np.shape(image)
        noise=np.zeros(shape=image.shape,dtype=np.uint8)
        # print(np.shape(image))
        #固定产生白噪点的个数
        count=0
        prob=0.95
        for i in range(h):
            for j in range(w):
                sand=random.random()
                if count<=50000 and sand>prob:
                    noise[i][j]=0
                    count+=1
                else:
                    noise[i][j]=image[i][j]
        cv2.imshow('image',noise)
        cv2.waitKey(0)
        cv2.imwrite('images/Exen_black.png',noise)
    
    #进行开运算的方式一,直接调用开运算函数
    def MorphologyExAnd(img_path='images/Exen_black.png'):
        #读取图片
        img_src=cv2.imread(img_path)
        img=cv2.resize(src=img_src,dsize=(500,500))
        #获取卷积核,这里使用矩阵的方式
        kernel=cv2.getStructuringElement(shape=cv2.MORPH_RECT,ksize=(3,3))
        #进行闭运算
        img=cv2.morphologyEx(src=img,op=cv2.MORPH_CLOSE,kernel=kernel,iterations=1)
        #显示图片
        cv2.imshow('img_src',img_src)
        cv2.imshow('img',img)
        #等待接收鼠标或者键值
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    #进行开运算方式2=腐蚀+膨胀
    def Erode_Dilate(img_path='images/Exen_black.png'):
        #读取图像
        img_src=cv2.imread(img_path)
        img=cv2.resize(src=img_src,dsize=(500,500))
        #获取卷积核
        kernel=cv2.getStructuringElement(shape=cv2.MORPH_RECT,ksize=(3,3))
        #首先进行膨胀操作
        img_dilate = cv2.dilate(src=img, kernel=kernel, iterations=1)
        #再进行腐蚀操作
        img_erode = cv2.erode(src=img_dilate, kernel=kernel, iterations=1)
        #显示图像
        cv2.imshow('img_src',img_src)
        cv2.imshow('img_dilate',img_erode)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
    
    if __name__ == '__main__':
        print('Pycharm')
        # ProduceBlackNoise()
        # MorphologyExAnd()
        Erode_Dilate()
    

    直接使用闭运算函数的结果:

    使用:膨胀+腐蚀方式

    总结:
    开运算是解决黑色图像部分中的白色噪点;
    闭运算解决的是白色图像部分中的黑色噪点。

    来源:Keep_Trying_Go

    物联沃分享整理
    物联沃-IOTWORD物联网 » Opencv中的开运算和闭运算操作讲解(python实现)

    发表评论