import numpy as np
import pandas as pd
我有一张图片,n
像素宽,m
像素高。这两个数字都是偶数。像素是正方形。像素值位于一个 numpy 数组中。
我需要计算每个像素中心到图像中心的距离。即紧邻中心的像素应该具有关联值sqrt(2)/2
。如果图像像一个棋盘,g6方块对应的像素应该有关联的距离值应该是(2.5^2+1.5^2)^0.5=2.91
我通过以下代码完成了任务:
image=np.zeros([2,4]) # let's say this is my image
df = pd.DataFrame(image)
distances = \
pd.DataFrame(
df.apply(
lambda row: (row.index+0.5-len(df.index)/2)**2,axis=0).to_numpy()+\
df.T.apply(
lambda row: (row.index+0.5-len(df.columns)/2)**2,axis=0).T.to_numpy())\
.apply(np.sqrt).to_numpy()
distances
将是:
array([[1.58113883, 0.70710678, 0.70710678, 1.58113883],
[1.58113883, 0.70710678, 0.70710678, 1.58113883]])
正如预期的那样。
有没有更好的办法?我希望有一个更短、更面向 numpy 或更透明的方法。
答案 0 :(得分:1)
更透明的方法是首先定义图像的中心,例如
在 openCV 中将数组作为图像读取:
img = cv2.imread("inputImage")
height, width = img.shape
x_center=(width/2)
y_center=(height/2)
然后对于 numpy/image 数组中的每个像素,您可以通过计算欧氏距离来计算 numpy 数组的每个像素与上述中心之间的距离:
D = dist.euclidean((xA, yA), (x_center, y_center))
PS:您可以简单地使用 numpy 中的 img.shape,但 openCV 为您提供了许多与距离计算相关的方法。
答案 1 :(得分:1)
除了 Numpy 中的这个简单实现之外,我不知道任何特定的算法可以做到这一点,即使用 indices(根据数组的形状创建索引数组)和 linalg.norm(计算范数)功能。请注意,我们还通过为 center[:,None,None]
中的新维度编制索引来使用 broadcasting(这是必要的,因为 indices
内在输出形状)。
import numpy as np
import pandas as pd
# Numpy function
def np_function(image):
center = np.array([(image.shape[0])/2, (image.shape[1])/2])
distances = np.linalg.norm(np.indices(image.shape) - center[:,None,None] + 0.5, axis = 0)
return distances
# Pandas function
def pd_function(image):
df = pd.DataFrame(image)
distances = \
pd.DataFrame(
df.apply(
lambda row: (row.index+0.5-len(df.index)/2)**2,axis=0).to_numpy()+\
df.T.apply(
lambda row: (row.index+0.5-len(df.columns)/2)**2,axis=0).T.to_numpy())\
.apply(np.sqrt).to_numpy()
return distances
对于 4000x6000 的图像,Numpy 的方法比我计算机中的原始函数快一个数量级以上。您也可以只计算从中心到一个八分圆的距离,然后方便地将结果复制到剩余的八分圆(利用对称性),但这可能只对大图像有用,恕我直言。