【问题标题】:Extract x,y coordinates of each pixel from an image in Python在 Python 中从图像中提取每个像素的 x,y 坐标
【发布时间】:2020-07-02 02:38:49
【问题描述】:

假设我有一张彩色图像,已加载到一个 numpy 尺寸数组 (200 x 300 x 3) 中。图像中总共有 60,000 个像素。我正在尝试从代表像素 1 的 左上角 开始提取每个像素的宽度、高度 (x,y) 坐标,这样:

pixel#   x    y
1        0    0
2        1    0
.
.
301      0    1
302      1    1
.
.
60,000   299 199   

我很想使用 for 循环以更手动的方式执行此操作,但是否有库或更有效的方法来获取每个像素的坐标值?

【问题讨论】:

  • 我不清楚这从哪里开始。你到底在提取什么?看起来上面的 DataFrame 可以用 2 个简单的数字 X=300 和 Y=200 创建,基本上没有其他信息。是这样吗?

标签: python pandas opencv image-processing pca


【解决方案1】:

在您的示例中,像素索引顺序表示行优先顺序。鉴于此,您可以使用以下函数获取任意像素的 x 和 y 值:

def idx_to_xy(idx):
    '''
    Assumes idx starts at one, as in the provided example
    '''
    x = (idx - 1) % 300
    y = (idx - 1) // 300

    return x, y

for px in [1, 2, 301, 302, 60000]:
    x, y = idx_to_xy(px)
    print("%5d    %3d  %3d" %(px, x, y))

# pixels     x    y
#      1      0    0
#      2      1    0
#    301      0    1
#    302      1    1
#  60000    299  199

【讨论】:

    【解决方案2】:

    由于您显示的格式似乎是 pandas,我将使用 pandas 显示输出,但您可以只使用打印。 :)

    我什至将n-dimension 作为 cmets 提供了您的问题的解决方案。

    import numpy as np
    from itertools import product
    
    arr = np.array([
        list(range(300))
        for _ in range(200)
    ])
    
    print(arr.shape)
    # (200, 300)
    
    pixels = arr.reshape(-1)
    
    """ n-dimension solution
        coords = map(range, arr.shape)
        indices = np.array(list( product(*coords) ))
    """
    xs = range(arr.shape[0])
    ys = range(arr.shape[1])
    indices = np.array(list(product(xs, ys)))
    
    import pandas as pd
    pd.options.display.max_rows = 20
    
    index = pd.Series(pixels, name="pixels")
    df = pd.DataFrame({
        "x" : indices[:, 0],
        "y" : indices[:, 1]
    }, index=index)
    print(df)
    #           x    y
    # pixels          
    # 0         0    0
    # 1         0    1
    # 2         0    2
    # 3         0    3
    # 4         0    4
    # 5         0    5
    # 6         0    6
    # 7         0    7
    # 8         0    8
    # 9         0    9
    # ...     ...  ...
    # 290     199  290
    # 291     199  291
    # 292     199  292
    # 293     199  293
    # 294     199  294
    # 295     199  295
    # 296     199  296
    # 297     199  297
    # 298     199  298
    # 299     199  299
    
    # [60000 rows x 2 columns]
    

    【讨论】:

      【解决方案3】:

      假设我理解您的问题,这是使用 Python/OpenCV 实现此目的的一种非常简单的方法。将图像转换为灰度,然后使用 np.where()。

      import cv2
      import numpy as np
      
      # create red image
      img = np.full((10,10,3), (0,0,255), dtype=np.uint8)
      
      # convert to grayscale
      gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
      
      # get coordinates (y,x) --- alternately see below for (x,y)
      yx_coords = np.column_stack(np.where(gray >= 0))
      print (yx_coords)
      
      print ('')
      
      # get coordinates (x,y)
      xy_coords = np.flip(np.column_stack(np.where(gray >= 0)), axis=1)
      print (xy_coords)
      


      (x,y) 的返回值:

      [[0 0]
       [1 0]
       [2 0]
       [3 0]
       [4 0]
       [5 0]
       [6 0]
       [7 0]
       [8 0]
       [9 0]
       [0 1]
       [1 1]
       [2 1]
       [3 1]
       [4 1]
       [5 1]
       [6 1]
       [7 1]
       [8 1]
       [9 1]
       [0 2]
       [1 2]
       [2 2]
       [3 2]
       [4 2]
       [5 2]
       [6 2]
       [7 2]
       [8 2]
       [9 2]
       [0 3]
       [1 3]
       [2 3]
       [3 3]
       [4 3]
       [5 3]
       [6 3]
       [7 3]
       [8 3]
       [9 3]
       [0 4]
       [1 4]
       [2 4]
       [3 4]
       [4 4]
       [5 4]
       [6 4]
       [7 4]
       [8 4]
       [9 4]
       [0 5]
       [1 5]
       [2 5]
       [3 5]
       [4 5]
       [5 5]
       [6 5]
       [7 5]
       [8 5]
       [9 5]
       [0 6]
       [1 6]
       [2 6]
       [3 6]
       [4 6]
       [5 6]
       [6 6]
       [7 6]
       [8 6]
       [9 6]
       [0 7]
       [1 7]
       [2 7]
       [3 7]
       [4 7]
       [5 7]
       [6 7]
       [7 7]
       [8 7]
       [9 7]
       [0 8]
       [1 8]
       [2 8]
       [3 8]
       [4 8]
       [5 8]
       [6 8]
       [7 8]
       [8 8]
       [9 8]
       [0 9]
       [1 9]
       [2 9]
       [3 9]
       [4 9]
       [5 9]
       [6 9]
       [7 9]
       [8 9]
       [9 9]]
      


      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-17
        • 1970-01-01
        • 1970-01-01
        • 2021-07-10
        • 2021-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多