通过形状

时间:2017-05-10 06:06:44

标签: swift performance matrix ndimage

假设我有一个2D数组

let img = [[0, 1, 2, 1, 3, 0],
           [1, 1, 1, 1, 1, 1],
           [1, 2, 1, 0, 1, 1],
           [1, 1, 1, 1, 1, 1],
           [0, 1, 4, 1, 5, 0],
           ]

let shape = [[0,1,0],
             [1,1,1],
             [0,1,0]]

let diamon_shape = [[0, 0, 1, 0, 0],
                    [0, 1, 1, 1, 0],
                    [1, 1, 1, 1, 1],
                    [0, 1, 1, 1, 0],
                    [0, 0, 1, 0, 0]]

我将形状(菱形)的中心放在每一列上,然后每行获得形状内的最大数字(= 1),然后用最大数字替换形状中心。这就像图像形态学中的膨胀和侵蚀一样

这是我在Swift中的实现:

class func maximum_filter(image:[[Int]], shape:[[Int]]) -> [[Int]]{
        let wShape = shape[0].count
        let hShape = shape.count
        let wImage = image[0].count
        let hImage = image.count
        var final = Array(repeating: Array(repeating: 0.0, count: image[0].count), count: image.count)
        for i in 0..<hImage {
            for ii in 0..<wImage {
                var startOfWZ = 0
                var startOfHZ = 0
                var wStart = ii - wShape/2
                if wStart < 0 {
                    wStart = 0
                    startOfWZ = 1
                }
                var wEnd = ii + wShape/2
                if wEnd >= wImage {
                    wEnd = wImage - 1
                }
                var hStart = i - hShape/2
                if hStart < 0 {
                    hStart = 0
                    startOfHZ = 1
                }
                var hEnd = i + hShape/2
                if hEnd >= hImage {
                    hEnd = hImage - 1
                }

                var hz = startOfHZ
                var maxNumber = 0.0
                for x in hStart...hEnd {
                    var wz = startOfWZ
                    for xx in wStart...wEnd {
                        if shape[hz][wz] == 1 {
                            let currentNumber = image[x][xx]
                            if currentNumber > maxNumber {
                                maxNumber = currentNumber
                            }
                        }
                        wz += 1
                    }
                    hz += 1
                }
                final[i][ii] = maxNumber
            }
        }

        return final
    }

前2个循环我迭代矩阵的每个元素以将形状的中心放在上面。然后接下来的2个循环我得到图像映射的所有元素与元素(= 1)的形状然后比较它们以获得最大数量。没什么复杂的。 结果是:

1 2 2 3 3 3
1 2 2 1 3 1 
2 2 2 1 1 1 
1 2 4 1 5 1
1 4 4 5 5 5 

但是当我尝试使用真实图像4096x4096(Double中的输入而不是Int中的样本)并且钻石形状是41x41。与python(1秒)相比,性能超级慢(10秒)。这里是我在python result = maximum_filter(img, footprint=shape)中使用的代码。我无法看到maximum_filter的源代码,所以我自己实现了它。我得到了相同的结果,但性能比他们的慢得多。

1 个答案:

答案 0 :(得分:0)

您不能指望使用您想到的第一种算法从框架中获得与专用函数相同的性能。 Python函数背后的代码可能使用高级内存管理技术和不同的逻辑进行优化。

正如这可能意味着差异的一个例子,这是一个相同功能的天真算法,在具有41x41十字准线形状的4096 x 4096图像上执行速度比你快20倍:

npm install -g polymer-cli@next

我甚至没有进入平面存储器模型,范围检查和保留周期优化,寄存器移位,汇编代码,或者您可能在未看到的代码中使用的任何100种技术。