将二维Numpy像素数组的坐标传递给距离函数

4
我正在使用OpenCV和numpy开发一个图像处理程序。对于大多数像素操作,我能够通过使用np.vectorize()避免嵌套的for循环,但其中一个需要实现的函数需要一个参数'距离中心的距离',或者基本上是正在处理的点的坐标。
伪例子:
myArr = [[0,1,2]
         [3,4,5]]

def myFunc(val,row,col):
    return [row,col]

f = np.vectorize(myFunc)
myResult = f(myArr,row,col)

我显然无法从向量化数组中获得elemX和elemY,但是否有另一个我可以在这种情况下使用的numpy函数,还是必须使用 for 循环?有没有一种使用openCV的方法来实现?
我需要通过以下函数处理每个像素: f(i, j) = 1 / (1 + d(i, j) / L),其中d(i,j)是点到图像中心的欧几里得距离。
2个回答

1
您可以使用以下代码(这只是一个示例,有很多方法可以实现)获取距离中心的数组:
    import numpy as np

myArr = np.array([[0,1,2], [3,4,5]])

nx, ny = myArr.shape
x = np.arange(nx) - (nx-1)/2.  # x an y so they are distance from center, assuming array is "nx" long (as opposed to 1. which is the other common choice)
y = np.arange(ny) - (ny-1)/2.
X, Y = np.meshgrid(x, y)
d = np.sqrt(X**2 + Y**2)

#  d = 
#  [[ 1.11803399  1.11803399]
#   [ 0.5         0.5       ]
#   [ 1.11803399  1.11803399]]

然后你可以通过以下方式计算 f(i, j)
f = 1/(1 + d/L)


顺便提一下,你大量使用 np.vectorize() 有点可疑。你确定它正在做你想要的事情吗?你注意到文档中的语句了吗 the documentation:

向量化函数主要是为了方便而提供的,而不是为了性能。实现本质上是一个 for 循环。

通常最好只需以向量化的形式编写代码(例如我的 f 行,无论 L 是数组还是缩放器,都可以工作),而不使用 numpy.vectorize(),这是两个不同的东西。


顺便说一下,昨晚我开始编写Python代码了;-)非常感谢您的建议,我还没有时间学习最佳实践! - xShirase
1
@xShirase: 尤其是在这种情况下,我会完全跳过使用 np.vectorize。使用它将让你走上错误的轨道(在多年使用numpy的工作中,我从未使用过它)。相反,numpy应该使编写代码更容易并且运行更快,就像上面的 f 表达式;这两个都是你想要的。也许一个超短的numpy教程可以帮助你正确入门。 - tom10
我通常使用Node.JS编码,但这次我必须实现一些繁重的矩阵计算,所以不得不转向Python,因此我的代码肯定没有优化。我不确定我理解这部分内容:“与另一个常见选择1相反”,你能推荐一个好的教程吗? - xShirase
1
@xShirase:在考虑图像所表示的实际大小时,需要考虑相当多的变化,这就是为什么我在这里明确地写出来的原因。看起来你想让你的数组表示与每个轴上的像素数量相对应的图像大小。人们经常需要的另一件常见事情是像素的位置从0到1沿两个轴运行,或者是从-0.5到0.5之类的东西。无论如何,所有这些都只涉及对“x”和“y”行进行几个简单的更改。 - tom10
好的,明白了,感谢你的建议,我现在要去学习一下numpy的速成课程!另外,由于这个图像来自OpenCV,所以shape返回的是y,x而不是x,y(而RGB是BGR,想象一下)。 - xShirase

1

np.vectorize不能加速代码,你可以通过以下方式进行向量化:

# This compute distance between all points of MyArray and the center

dist_vector= np.sqrt(np.sum(np.power(center-MyArray,2),axis=1))


# F will contain the target value for each point

F = 1./(1 + 1. * dist_vector/L)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接