• OpenCV笔记(2)(高斯平滑、腐蚀和膨胀、开闭运算、礼帽和黑帽、Sobel及其他算子)


    一、高斯平滑(模糊)

    def gaussian_blur(image):
        # 设置ksize来确定模糊效果
        img = cv.GaussianBlur(image, (5, 5), 0)
        cv.imshow('img', img)
    
        # 不通过ksize来设置高斯核大小,通过设置高斯分布公式中的sigma
        img2 = cv.GaussianBlur(image, (0, 0), 1)
        cv.imshow('img2', img2)

    在高斯平滑中,高斯核中所有数字加起来应该为1,这样才能保证图片只发生平滑效果,而不影响亮度等其他效果。

    例如3x3的高斯核如下所示:

    二、边缘保留滤波(EPF)

    高斯双边模糊(美颜):

    def bi_blur(image):
        img = cv.bilateralFilter(image, 0, 100, 5)
        cv.imshow('img', img)

    从效果可以看出,边缘保留的还不错,而非边缘进行了模糊。双边模糊的效率比较低,特别是sigmaSpace比较大的时候。

    cv.bilateralFilter()函数的参数:

    src:原图像

    d:过滤过程中每个像素领域的直径范围,若非正数,则从sigmaSpace计算

    sigmaColor:值越大,表示像素领域内有多宽的颜色(颜色范围)会被混在一起

    sigmaSpace:如果值较大,表示颜色相近的较远像素(空间范围)将互相影响,从而使更大区域足够相似的颜色获取相同的颜色。

    三、腐蚀和膨胀

    腐蚀操作:

    # 腐蚀操作,用于去除一些细小的白色颗粒或线条
    def erode_img(image):
        kernel = np.ones((5,5),np.uint8)
        # 当核尺寸越大时,每次腐蚀的程度越大,iter是操作中叠加几次腐蚀
        img = cv.erode(image,kernel,iterations = 1)
        cv.imshow('img',img)

    膨胀操作:

    膨胀可以说是腐蚀的反操作:

    # 膨胀操作,用于去除一些细小的黑色漏洞
    def dilate_img(image):
        kernel = np.ones((5, 5), np.uint8)
        img = cv.dilate(image, kernel, iterations=1)
        cv.imshow('img', img)

    结合腐蚀和膨胀:

    结合腐蚀和膨胀,可以消除一些细小的不需要的部分,然后再复原。

    def combo_proc(image):
        kernel = np.ones((5, 5), np.uint8)
        img = cv.dilate(image, kernel, iterations=1)
        img2 = cv.erode(img, kernel, iterations=1)
        cv.imshow('img2', img2)

    四、开运算和闭运算

    # 开操作:先腐蚀再膨胀
    def open_proc(image):
        kernel = np.ones((5, 5), np.uint8)
        opening = cv.morphologyEx(image, cv.MORPH_OPEN, kernel)
        cv.imshow('opening', opening)
    
    # 闭操作:先膨胀再腐蚀
    def close_proc(image):
        kernel = np.ones((5, 5), np.uint8)
        closing = cv.morphologyEx(image, cv.MORPH_CLOSE, kernel)
        cv.imshow('closing', closing)

    结合开闭运算:

    # 先做开操作,再做闭操作
    def open_close_proc(image):
        kernel = np.ones((5, 5), np.uint8)
        opening = cv.morphologyEx(image, cv.MORPH_OPEN, kernel)
        closing = cv.morphologyEx(opening, cv.MORPH_CLOSE, kernel)
        cv.imshow('closing', closing)

    梯度运算:

    # 梯度操作:膨胀 - 腐蚀
    def gradient_proc(image):
        kernel = np.ones((3, 3), np.uint8)
        gradient = cv.morphologyEx(image, cv.MORPH_GRADIENT, kernel)
        cv.imshow('gradient', gradient)

    五、礼帽和黑帽

    礼帽是通过原图片减去开操作后的图像,得到其中的多于细小部分(字边上的白色细线)。

    黑帽是通过闭操作后的图像减去原图像,得到其中的细小泄漏部分(字中间的黑色细线)。

    礼帽:tophat

    # tophat 礼帽
    def tophat_img(image):
        kernel = np.ones((3, 3), np.uint8)
        img = cv.morphologyEx(image, cv.MORPH_TOPHAT, kernel)
        cv.imshow('img', img)

    黑帽:blackhat

    # blackhat 黑帽
    def blackhat_img(image):
        kernel = np.ones((3, 3), np.uint8)
        img = cv.morphologyEx(image, cv.MORPH_BLACKHAT, kernel)
        cv.imshow('img', img)

    六、Sobel算子

    def sobel_proc(image):
        # 这里的cv.CV_64F用来保存所有的梯度(不管正负),1,0是dx,dy表示计算横向梯度
        sobelx = cv.Sobel(image, cv.CV_64F, 1, 0, ksize=3)
        # 将所有梯度取绝对值
        sobelx = cv.convertScaleAbs(sobelx)
        cv.imshow('sobelx', sobelx)
        
        # 计算y方向的梯度
        sobely = cv.Sobel(image, cv.CV_64F, 0, 1, ksize=3)
        # 将所有梯度取绝对值
        sobely = cv.convertScaleAbs(sobely)
        cv.imshow('sobely', sobely) 

    当计算X,Y方向的梯度时,Sobel算子分别为: 

     

    X方向是右边像素减去左边像素,Y方向是上面像素减去下面的像素。

    将XY方向的梯度合并起来:

    def sobel_proc(image):
        # 这里的cv.CV_64F用来保存所有的梯度(不管正负),1,0是dx,dy表示计算横向梯度
        sobelx = cv.Sobel(image, cv.CV_64F, 1, 0, ksize=3)
        # 将所有梯度取绝对值
        sobelx = cv.convertScaleAbs(sobelx)
        # cv.imshow('sobelx', sobelx)
    
        # 计算y方向的梯度
        sobely = cv.Sobel(image, cv.CV_64F, 0, 1, ksize=3)
        # 将所有梯度取绝对值
        sobely = cv.convertScaleAbs(sobely)
        # cv.imshow('sobely', sobely)
    
        # 将x和y方向的梯度合并起来,类似于sobelx+sobely
        sobelxy = cv.addWeighted(sobelx, 1, sobely, 1, 0)
        cv.imshow('sobelxy', sobelxy)
    
        # 不建议使用这种方式,有问题
        sobelxy2 = cv.Sobel(image, -1, 1, 1, ksize=3)
        cv.imshow('sobelxy2', sobelxy2)

    建议使用addWeight()的方式进行合并,而不建议在一个Sobel计算中同时计算xy方向的梯度。

    应用到图片上:

    彩色图:

    灰度图:

    七、其他算子介绍

    Scharr算子:(读/ʃɑr/)

    scharr = cv.Scharr(image,cv.CV_64F, 1, 0)
    scharr = cv.convertScaleAbs(scharr)

     Scharr算子和Sobel算子类似,只是数值比Sobel大很多,这就导致Scharr算子灵敏度更高,噪声影响较大。如下图:

    Laplacian算子: 

    拉普拉斯算子是图像的离散二阶导数,用于发现边缘突变,但对于噪声来说比较灵敏,一般配合其他技术一起使用。

     

    laplacian = cv.Laplacian(image,cv.CV_64F)
    laplacian = cv.convertScaleAbs(laplacian)

    Laplacian算是和前面的两种算子不同,前面的两种算子都属于一阶导数,而Laplacian算子是用于计算二阶导数的。体现的是边缘的突变度,即梯度的变化度。效果如图:

  • 相关阅读:
    SpringCloud-Hystrix Dashboard 之 Unable to connect to Command Metric Stream
    try() catch{}
    git使用和操作
    外部服务器使用jedis操作redis数据库
    Tomcat部署spring boot项目
    java成神之路截图
    innodb 死锁分析之相关表结构说明
    mysql 死锁案例及分析过程
    Head First设计模式之观察者(Observer)模式(二)
    Head First设计模式之策略模式(Strategy)
  • 原文地址:https://www.cnblogs.com/leokale-zz/p/11346993.html
Copyright © 2020-2023  润新知