【问题标题】:Calculate pixel distance from centre of image计算距图像中心的像素距离
【发布时间】:2021-02-28 18:58:10
【问题描述】:
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 或更透明的方法。

【问题讨论】:

    标签: python pandas numpy


    【解决方案1】:

    一种更透明的方法是首先定义图像的中心,即类似

    1. 在 openCV 中将数组读取为图像:

       img = cv2.imread("inputImage")
       height, width = img.shape
      
       x_center=(width/2)
       y_center=(height/2)
      
    2. 然后对于 numpy/image 数组中的每个像素,您可以通过计算欧几里得距离来计算 numpy 数组的每个像素与上述中心之间的距离:

      D = dist.euclidean((xA, yA), (x_center, y_center))

    PS : 您可以简单地使用 numpy 中的 img.shape,但 openCV 为您提供了许多与距离计算相关的方法。

    【讨论】:

    • 什么是 xA 和 yA?
    • xA 和 yA 是您要计算到中心距离的像素坐标
    • 因此您将传递 numpy 数组的每个像素并计算其到上面定义的中心的距离。
    • 你能在你的答案中提供代码吗?我想要每个像素的距离。
    【解决方案2】:

    我不知道任何特定的算法可以做到这一点,除了这个在 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 的方法比我电脑中的原始函数快一个数量级以上。您也可以只计算从中心到一个八分圆的距离,然后将结果方便地复制到其余八分圆(利用 simmetry),但这可能只对大图像 imho 有价值。

    【讨论】:

      猜你喜欢
      • 2021-05-26
      • 2020-07-29
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多