【问题标题】:Improving Canny Edge Detection改进 Canny 边缘检测
【发布时间】:2020-05-10 14:53:11
【问题描述】:

当我在图纸上运行 cv.Canny 边缘检测器时,它会检测到数百个密集填充在阴影区域中的小边缘。我怎样才能让它停止这样做,同时仍然检测到眼睛和鼻子等较轻的特征?我也试过模糊。

这是一个示例,与 online photo tool 相比。

Original image.
Output of online tool.
My python program

这是我的代码:

def outline(image, sigma = 5):
    image = cv.GaussianBlur(image, (11, 11), sigma)
    ratio = 2
    lower = .37 * 255
    upper = lower * ratio
    outlined = cv.Canny(image, lower, upper)

    return outlined

我该如何改进它?

【问题讨论】:

    标签: python opencv image-processing


    【解决方案1】:

    这是在 Python/OpenCV 中执行此操作的一种方法。

    Morphologic edge out 是蒙版和扩张蒙版之间的绝对差异

    • 读取输入
    • 转换为灰色
    • 阈值(作为掩码)
    • 扩大阈值图像
    • 计算绝对差
    • 将其极性反转为边缘图像
    • 保存结果

    输入:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread("cartoon.jpg")
    
    # convert to gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # threshold
    thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY)[1]
    
    # morphology edgeout = dilated_mask - mask
    # morphology dilate
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
    dilate = cv2.morphologyEx(thresh, cv2.MORPH_DILATE, kernel)
    
    # get absolute difference between dilate and thresh
    diff = cv2.absdiff(dilate, thresh)
    
    # invert
    edges = 255 - diff
    
    # write result to disk
    cv2.imwrite("cartoon_thresh.jpg", thresh)
    cv2.imwrite("cartoon_dilate.jpg", dilate)
    cv2.imwrite("cartoon_diff.jpg", diff)
    cv2.imwrite("cartoon_edges.jpg", edges)
    
    # display it
    cv2.imshow("thresh", thresh)
    cv2.imshow("dilate", dilate)
    cv2.imshow("diff", diff)
    cv2.imshow("edges", edges)
    cv2.waitKey(0)
    


    阈值图像:

    扩张的阈值图像:

    不同的图像:

    边缘图像:

    【讨论】:

    • 谢谢!我认为精明的边缘检测是最好的选择。它在其他示例上运行良好。为什么你认为你的方法在这个上比 canny 效果更好?您是否希望它在某种图像上效果更好,或者您认为与 cv2.canny 相比,您的方法总体上会更好?
    • 在灰色命令和阈值命令median = cv2.medianBlur(gray, 3)之间添加中值过滤。或者使用任何其他不会影响边缘检测的良好噪声过滤过程,否则您可能需要修改膨胀量。
    • 如果你愿意使用 Python Wand 而不是 OpenCV,那么 Python Wand 是基于 ImageMagick 的,它还有其他的噪声过滤过程。 OpenCV 中另一种可能的方法是使用 kmeans 聚类而不是简单的阈值化。但我还没有测试过。
    • 我不相信你可以改变 Canny 的行为来解决这个问题。
    • 您的其他工具会为该额外图像生成什么?该其他站点使用其他一些基于卷积的方法。但我无法遵循他们的编码风格。
    【解决方案2】:

    通过将内核维度从 (11, 11) 更改为 (0, 0),我成功地使 cv.Canny 给出了令人满意的结果,允许内核由 sigma 动态确定。通过这样做并调整 sigma,我得到了很好的结果。此外,cv.imshow 会扭曲图像,所以当我使用它进行测试时,结果看起来比实际差很多。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 2017-04-22
      • 1970-01-01
      • 2019-01-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多