Извлечь координаты x, y каждого пикселя из изображения в Python - PullRequest
0 голосов
/ 21 марта 2020

Допустим, у меня есть цветное изображение, которое я загрузил в массив размеров numpy (200 x 300 x 3). Всего на изображении 60000 пикселей. Я пытаюсь извлечь координаты ширины, высоты (x, y) каждого пикселя, начиная с в верхнем левом верхнем углу , представляющего пиксель 1, таким образом:

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

I'm искушение использовать для l oop, чтобы сделать это в более ручном характере, но есть ли библиотеки или более эффективные способы получить эти значения координат для каждого пикселя как такового?

Ответы [ 3 ]

1 голос
/ 21 марта 2020

Так как формат, который вы показываете, кажется pandas, я представлю вывод с pandas, но вы можете просто использовать простую распечатку. :)

Я даже включил n-dimension решение вашей проблемы в качестве комментариев.

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]
1 голос
/ 21 марта 2020

Вот один очень простой способ сделать это с помощью 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]]


1 голос
/ 21 марта 2020

В вашем примере порядок индекса пикселя указывает порядок основной строки. Учитывая это, вы можете получить значения 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
...