• openCV学习笔记(2)


    以下所有操作建议使用png格式的原始图片,使用jpg图片虽然不会出错,但一些操作的结果不太好,原因未知,可能是png格式保留信息更多?

    (1)图像形态学

    --腐蚀操作

    先读进来原始图像

    import numpy as np
    import cv2 as cv
    from matplotlib import pyplot as plt
    img = cv.imread("circle.jpg")
    plt.imshow(img)
    plt.show()

     图像是一个⚪周围有一些杂乱的线

    我们进行腐蚀操作cv.erode(图像,卷积核,操作次数),看看结果

    kernel = np.ones((30,30),np.uint8)#设置一个卷积核大小为(30,30),指定的核越大,边缘被腐蚀的可能性越大
    erosion1 = cv.erode(img,kernel,iterations = 1)#执行一次腐蚀
    erosion2 = cv.erode(img,kernel,iterations = 2)#执行两次腐蚀
    erosion3 = cv.erode(img,kernel,iterations = 3)
    res = np.hstack((erosion1,erosion2,erosion3))
    plt.imshow(res)
    plt.show()

    可以看到杂线条没了,且“想内塌陷”

     --膨胀操作,我们在腐蚀的结果上膨胀

    kernel = np.ones((30,30),np.uint8)
    dilate1 = cv.dilate(img,kernel,iterations = 1)
    dilate2 = cv.dilate(img,kernel,iterations = 2)
    dilate3 = cv.dilate(img,kernel,iterations = 3)
    dilate4 = cv.dilate(img,kernel,iterations = 4)
    res = np.hstack((dilate1,dilate2,dilate3,dilate4))
    plt.imshow(res)
    plt.show()

     可以发现,第一次膨胀后我们得到了一个完整的⚪但我们的杂线条已经消失了,再继续进行膨胀,图像越来越大

    --开运算和闭运算

    开运算就是先腐蚀再膨胀

    闭运算就是先膨胀再腐蚀

    拿原始图像来看一下效果

    开运算结果:

    opening = cv.morphologyEx(img,cv.MORPH_OPEN,kernel)
    plt.imshow(opening)
    plt.show()

     闭运算结果:

    closing = cv.morphologyEx(img,cv.MORPH_CLOSE,kernel)
    plt.imshow(closing)
    plt.show()

     --图像梯度运算

    #梯度运算等于膨胀-腐蚀
    kernel = np.ones((7,7),np.uint8)
    gradient = cv.morphologyEx(img,cv.MORPH_GRADIENT,kernel)
    plt.imshow(gradient)
    plt.show()

     这样我们就得到了图像的轮廓了

    --礼帽和黑帽

    礼帽 = 原始输入 - 开运算结果(开运算为先腐蚀再膨胀结果为原始的不带杂线的,最终结果为那些原始图像的杂线)
    黑帽 = 闭运算 - 原始输入 (闭运算为先膨胀再腐蚀结果为原始图像加深杂线,最终为原始整体轮廓)

    #礼帽
    tophat = cv.morphologyEx(img,cv.MORPH_TOPHAT,kernel)
    plt.imshow(tophat)
    plt.show()

    #黑帽
    blackhat = cv.morphologyEx(img,cv.MORPH_BLACKHAT,kernel)
    plt.imshow(blackhat)
    plt.show()

     (2)图像梯度处理

    超级详细的讲解:https://blog.csdn.net/poem_qianmo/article/details/25560901

    --sobel算子

    sobel原型:Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]) -> dst

    src:图片

    ddepth:图像深度,当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数

     dx =1代表水平方向,dy=1代表竖直方向

    ksize:代表算子大小

    import cv2 as cv
    import numpy as np
    def cvshow(img):
        cv.imshow("img",img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    img = cv.imread("pie.png")
    cvshow(img)
    #进行SObel算子
    sobel = cv.Sobel(img,cv.CV_64F,1,0,ksize=3)
    sobel = cv.convertScaleAbs(sobel)#取绝对值
    cvshow(sobel)

    当我们不加取绝对值时,结果为一半,加上取绝对值就可以获取到完整的

     这里建议分别算X方向的sobel和Y方向的sobel再加一起,这样会比直接dx=1,dy=1一起算的更清晰

    --Scharr算子和laplacian算子

    import cv2 as cv
    import numpy as np
    def cvshow(img):
        cv.imshow("img",img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    img = cv.imread("car.jpg")
    scharr_x = cv.Scharr(img,cv.CV_64F,1,0)
    scharr_y = cv.Scharr(img,cv.CV_64F,0,1)
    scharr_x = cv.convertScaleAbs(scharr_x)
    scharr_y = cv.convertScaleAbs(scharr_y)
    scharr_xy = cv.addWeighted(scharr_x,0.5,scharr_y,0.5,0)
    
    laplacian = cv.Laplacian(img,cv.CV_64F)
    laplacian = cv.convertScaleAbs(laplacian)
    res = np.hstack((scharr_xy,laplacian))
    cvshow(res)

     左边为scharr算子,右边为拉普拉多算子,右边差不多只有主体

    再对比一下3个的效果,从左至右分别为sobel,scharr,laplacian

    import cv2 as cv
    import numpy as np
    def cvshow(img):
        cv.imshow("img",img)
        cv.waitKey(0)
        cv.destroyAllWindows()
    img = cv.imread("lena.jpg",0)
    sobel_x = cv.Sobel(img,cv.CV_64F,1,0,ksize=3)
    sobel_y = cv.Sobel(img,cv.CV_64F,0,1,ksize=3)
    sobel_x = cv.convertScaleAbs(sobel_x)
    sobel_y = cv.convertScaleAbs(sobel_y)
    sobel = cv.addWeighted(sobel_x,0.5,sobel_y,0.5,0)
    
    scharr_x = cv.Scharr(img,cv.CV_64F,1,0)
    scharr_y = cv.Scharr(img,cv.CV_64F,0,1)
    scharr_x = cv.convertScaleAbs(scharr_x)
    scharr_y = cv.convertScaleAbs(scharr_y)
    scharr_xy = cv.addWeighted(scharr_x,0.5,scharr_y,0.5,0)
    
    laplacian = cv.Laplacian(img,cv.CV_64F)
    laplacian = cv.convertScaleAbs(laplacian)
    res = np.hstack((sobel,scharr_xy,laplacian))
    cvshow(res)

     整体来看,scharr算子保留了最多的细节,但是连通噪点也一起保留了下来,sobel算子保留了大部分最主要的轮廓信息,laplacian只有最主体的信息

    以上这一切的处理正是为了我们真正做轮廓处理做准备

  • 相关阅读:
    webstorm编辑器使用
    css深入理解z-index
    vue-cli安装失败问题
    html5 离线存储
    ESXI安装
    文档相似性匹配
    Hibernate基础
    云存储技术
    Signs of a poorly written jQuery plugin 翻译 (Jquery插件开发注意事项,Jquey官方推荐)
    Jquery类级别与对象级别插件开发
  • 原文地址:https://www.cnblogs.com/Truedragon/p/12916219.html
Copyright © 2020-2023  润新知