【问题标题】:How to quantize directions in Canny edge detector in python如何在python中量化Canny边缘检测器中的方向
【发布时间】:2018-04-13 08:20:32
【问题描述】:

我试图理解在 python 中 Canny 运算符的这种实现 我在 Rosettacode.org 上找到了,但不明白它是如何计算 thetaQ 的。为什么它在这个公式中使用 5 以及它如何量化方向? 有人可以帮帮我吗?

#!/bin/python
import numpy as np
from scipy.ndimage.filters import convolve, gaussian_filter
from scipy.misc import imread, imshow

def CannyEdgeDetector(im, blur = 1, highThreshold = 91, lowThreshold = 31):
    im = np.array(im, dtype=float) #Convert to float to prevent clipping values

    #Gaussian blur to reduce noise
    im2 = gaussian_filter(im, blur)

    #Use sobel filters to get horizontal and vertical gradients
    im3h = convolve(im2,[[-1,0,1],[-2,0,2],[-1,0,1]]) 
    im3v = convolve(im2,[[1,2,1],[0,0,0],[-1,-2,-1]])

    #Get gradient and direction
    grad = np.power(np.power(im3h, 2.0) + np.power(im3v, 2.0), 0.5)
    theta = np.arctan2(im3v, im3h)
    thetaQ = (np.round(theta * (5.0 / np.pi)) + 5) % 5 #Quantize direction

    #Non-maximum suppression
    gradSup = grad.copy()
    for r in range(im.shape[0]):
        for c in range(im.shape[1]):
            #Suppress pixels at the image edge
            if r == 0 or r == im.shape[0]-1 or c == 0 or c == im.shape[1] - 1:
                gradSup[r, c] = 0
                continue
            tq = thetaQ[r, c] % 4

            if tq == 0: #0 is E-W (horizontal)
                if grad[r, c] <= grad[r, c-1] or grad[r, c] <= grad[r, c+1]:
                    gradSup[r, c] = 0
            if tq == 1: #1 is NE-SW
                if grad[r, c] <= grad[r-1, c+1] or grad[r, c] <= grad[r+1, c-1]:
                    gradSup[r, c] = 0
            if tq == 2: #2 is N-S (vertical)
                if grad[r, c] <= grad[r-1, c] or grad[r, c] <= grad[r+1, c]:
                    gradSup[r, c] = 0
            if tq == 3: #3 is NW-SE
                if grad[r, c] <= grad[r-1, c-1] or grad[r, c] <= grad[r+1, c+1]:
                    gradSup[r, c] = 0

.........

【问题讨论】:

    标签: python-3.x image-processing scipy canny-operator


    【解决方案1】:

    atan2 返回 [-π,π] 范围内的值。公式(np.round(theta * (5.0 / np.pi)) + 5) 将其转换为范围 [0,10],并带有四舍五入的值。然后他们取模 5 的值,得到一个 [0,4] 范围内的整数,将 5 和 10 映射到 0、6 到 1 等。也就是说,0、-π 和 π 都映射到同一个整数. 后来他们取那个值以 4 为模,将 4 映射到 0。这是我不明白的部分。这对我来说似乎是错误的。这是映射:

    您可以看到,刚好高于 π/2 的值被映射为 3,而刚好低于 π/2 的值被映射为 2。此外,映射到 0 的角度范围是映射到其他角度的范围的两倍。我会以不同的方式对这些角度进行四舍五入。

    无论如何,Canny 滤波器的典型实现不会量化角度,而是使用插值来读取像素之间的值。

    此外,使用 Sobel 滤波器计算导数很奇怪,尤其是因为它们是在高斯滤波器之后应用的。此处应使用高斯滤波器的导数,以一步平滑和计算导数。

    【讨论】:

    • 太棒了!非常感谢您的详细解释。关于在高斯之后使用 Sobel,在 OpenCV 文档中提到过:docs.opencv.org/2.4/doc/tutorials/imgproc/imgtrans/…
    • 是的,我在很多地方都见过这种情况。 Canny 的论文被引用了 28,000 多次,我敢打赌那些人中很少有人真正费心阅读他的论文。这是:pdfs.semanticscholar.org/55e6/…
    • 只是为了回答的完整性:论文持续了好几页来开发理想的边缘定位滤波器,然后他建议高斯的导数是该理想的有效近似。
    • 非常感谢。抱歉,我无法评价您的回答,因为我是新成员,系统不允许我这样做。再次感谢。我将尝试仅使用 Gaussian 来实现它。
    • 我试过了。它不允许我这样做。它记录了我的演员阵容,但由于我的声望低(少于 15 名)而没有公开展示。对于那个很抱歉 。 :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2012-04-16
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 2021-03-27
    相关资源
    最近更新 更多