Python отображает значение пикселя в его гистограмму с помощью cv2 - PullRequest
0 голосов
/ 24 апреля 2020

Для данного изображения есть ли быстрый способ сопоставить значение пикселя с его ячейкой?

img = cv2.imread('test_image.jpg')
hist_g = cv2.calcHist([img[x:x+w,y:y+h,:]], [1], None, [9], [0, 256])

Возвращает массив 9x1 с количеством пикселей, которые делятся на 9 ячеек в диапазоне от 0 до 256 . Я думаю.

Мне нужна матрица [x:x+w,y:y+h], в которой каждая запись имеет номер ячейки, на которую отображается пиксель. Как я могу это сделать?

Например, допустим, у меня есть матрица

x = np.array([[154, 192],[67,115]])

Я хотел бы вернуть матрицу

x_histcounts = np.array([[5, 7],[3,4]])

на основе cv2.calcHist([img[x:x+w,y:y+h,:]], [1], None, [9], [0, 256])

, поскольку 154 находится в 5-ом бункере, 192 - в 7-м бункере и т. Д. c.

1 Ответ

1 голос
/ 25 апреля 2020

Если вы хотите, чтобы пиксель карты отображался в 9 ячейках, вы можете преобразовать его в оттенки серого, а затем разделить на (256/9), используя //, чтобы получить целые числа

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

result = img_gray[x:x+w,y:y+h] // (256/9)

В calcHist Вы используете список каналов [1], поэтому вам нужна гистограмма только для одного канала, а это означает, что вам не нужно преобразовывать в оттенки серого, а используйте [..., ..., 1]

result = img[x:x+w, y:y+h, 1] // (256/9)

РЕДАКТИРОВАТЬ: Я проверил ваши данные в качестве примера [[154, 192], [67, 115]], и они дали мне [[5, 6], [2, 4]] вместо [[5, 7], [3, 4]]

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115]])
result = (x // (256/bins_number)).astype(int)

print('result:', result.tolist())

Использование Google "numpy histcounts matlab" Я также нашел Как мне повторить эту функцию Matlab в numpy? , который использует np.digitize() для репликации histcounts, и это также дает мне [[5, 6], [2, 4]] вместо [[5, 7], [3, 4]], но я не знаю, правильно ли я создаю диапазоны бинов.

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115]])

bins = [(256/bins_number)*x for x in range(1, bins_number+1)]
result = np.digitize(x, bins)

print('result:', result.tolist())
print('bins:', bins)

У меня нет Matlab, поэтому я попытался использовать histc() в Октаве

>> [a, b] = histc([154, 192, 67, 115], [ 28.44444444,  56.88888889,  
85.33333333, 113.77777778, 142.22222222, 170.66666667, 199.11111111, 227.55555556, 256. ])

a =

   0   1   0   1   1   1   0   0   0

b =

   5   6   2   4

, и это также дает мне [[5, 6], [2, 4]] вместо [[5, 7], [3, 4]]


РЕДАКТИРОВАТЬ: Я нашел numpy .histogram_bin_edges для генерации диапазонов бинов

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115], [0,1]])

bins = np.histogram_bin_edges(x, bins=9, range=(0, 256))

print('bins:', bins)

Но он добавляет 0 в качестве первого край поэтому позже он использует числа 1-9 вместо 0-8, но если вы используете bins[1:], то он по-прежнему использует числа 0-8

import numpy as np

bins_number = 9

x = np.array([[154, 192], [67, 115]])

bins = np.histogram_bin_edges(x, bins=9, range=(0, 255))
print('bins:', bins)

print('result:', np.digitize(x, bins[1:]).tolist())
...