简体   繁体   English

Python中的广义距离变换

[英]Generalized Distance Transform in Python

I'm currently trying to implement the GDT described by Felzenszwalb and Huttenlocher ( http://www.cs.cornell.edu/~dph/papers/dt.pdf ) inside of Python for an image processing algorithm.我目前正在尝试在 Python 内部实现 Felzenszwalb 和 Huttenlocher ( http://www.cs.cornell.edu/~dph/papers/dt.pdf ) 描述的 GDT 以用于图像处理算法。 However I used the algorithm described in the paper they published a few years back but got faulty results.然而,我使用了他们几年前发表的论文中描述的算法,但得到了错误的结果。 I found a C# implementation here: https://dsp.stackexchange.com/questions/227/fastest-available-algorithm-for-distance-transform/29727?noredirect=1#comment55866_29727我在这里找到了一个 C# 实现: https : //dsp.stackexchange.com/questions/227/fastest-available-algorithm-for-distance-transform/29727?noredirect=1 # comment55866_29727

And converted it to Python (which is pretty much the same I had before).并将其转换为 Python(这与我之前使用的几乎相同)。

This is my code:这是我的代码:

def of_column(dataInput):
    output = zeros(dataInput.shape)
    n = len(dataInput)

    k = 0
    v = zeros((n,))
    z = zeros((n + 1,))

    v[0] = 0
    z[0] = -inf
    z[1] = +inf

    s = 0

    for q in range(1, n):
        while True:
            s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]))

            if s <= z[k]:
                k -= 1
            else:
                break

        k += 1

        v[k] = q
        z[k] = s
        z[k + 1] = +inf

    k = 0

    for q in range(n):
        while z[k + 1] < q:
            k += 1

        output[q] = ((q - v[k]) * (q - v[k]) + dataInput[v[k]])

    return output

I still can't find my error.我仍然找不到我的错误。 When giving the algorithm a binary (boolean) numpy array it just returns the array itself not the Distance Transform.当给算法一个二进制(布尔)numpy 数组时,它只返回数组本身而不是距离变换。 Why is this not working in Python?为什么这在 Python 中不起作用?

I got it working after hours and hours.我在几个小时后开始工作。 The answer given in the link above implementing the code in C# suggests putting up the "white" areas to a very large number.上面在 C# 中实现代码的链接中给出的答案建议将“白色”区域设置为非常大的数字。 My dataInput array was a boolean array (0, 1).我的 dataInput 数组是一个布尔数组 (0, 1)。 I replaced all 1s with 2^32 and it works just fine.我用 2^32 替换了所有的 1,它工作得很好。 The higher the number the more blurry it gets.数字越大越模糊。 The lower the more similar to the source it gets.越低,与它获得的来源越相似。

I would like to add the function for 2D that works with the 1D function described previously:我想添加与前面描述的 1D 函数一起使用的 2D 函数:

############################################################################### 
# distance transform of 1d function using squared distance 
############################################################################### 
def dt_1d(dataInput, n):
    output = np.zeros(dataInput.shape)
    k = 0
    v = np.zeros((n,))
    z = np.zeros((n + 1,))
    v[0] = 0
    z[0] = -np.inf
    z[1] = +np.inf
    for q in range(1, n):
        s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]))
        while s <= z[k]:
            k -= 1
            s = (((dataInput[q] + q * q) - (dataInput[v[k]] + v[k] * v[k])) / (2.0 * q - 2.0 * v[k]))
        k += 1
        v[k] = q
        z[k] = s
        z[k + 1] = +np.inf

    k = 0
    for q in range(n):
        while z[k + 1] < q:
            k += 1
        value = ((q - v[k]) * (q - v[k]) + dataInput[v[k]])
        if value > 255: value = 255
        if value < 0: value = 0
        output[q] = value
    print output
    return output
############################################################################### 
# distance transform of 2d function using squared distance 
###############################################################################     
def dt_2d(dataInput):
    height, width = dataInput.shape
    f = np.zeros(max(height, width))
    # transform along columns
    for x in range(width):
        f = dataInput[:,x]
        dataInput[:,x] = dt_1d(f, height)
    # transform along rows
    for y in range(height):
        f = dataInput[y,:]
        dataInput[y,:] = dt_1d(f, width)
    return dataInput

I hope it helps.我希望它有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM