Найдите уникальные кортежи внутри массива с np.where - PullRequest
0 голосов
/ 23 апреля 2019

Я хочу найти уникальные цветовые кортежи внутри массива с np.where. Мой код на данный момент:

from __future__ import print_function
import numpy as np 

a = range(10)
b = range(10,20)
c = range(20,30)
d = np.array(zip(a, b, c))
print(d)
e = np.array(zip(c, b, a))
print(e)
search = np.array((1,11,21))
search2 = np.array((0,11,21))
print(search, search2)
f = np.where(d == search, d, e)
g = np.where(d == search2, d, e)
print(f)
print(g)

Когда я запускаю код, он правильно находит поиск кортежа на второй позиции. Но кортеж search2 также находится на первой позиции, хотя он не содержится в уникальном кортеже внутри массива. Как я могу определить в numpy, что внутри массива должны быть найдены только уникальные кортежи, так что для g это дает значение

[[20 10  0]  [21 11  1]  [22 12  2]  
 [23 13  3]  [24 14  4]  [25 15  5]  
 [26 16  6]  [27 17  7]  [28 18  8]  [29 19  9]]

, но все равно находит уникальный поиск кортежей и выдает f

[[20 10  0]  [ 1 11 21]  [22 12  2]  
 [23 13  3]  [24 14  4]  [25 15  5]  
 [26 16  6]   [27 17  7]  [28 18  8]  [29 19  9]]

EDIT:

ОК, поэтому текущая проблема заключается в написании GIF-декодера на python. У меня есть предыдущий кадр с именем image_a и следующий кадр с именем image_b. image_b содержит пиксели с определенным набором цветов прозрачности, который в данном конкретном случае называется transp_color для загруженных изображений (0, 16, 8). Предполагается, что подпрограмма заменяет все эти записи этим набором цветов значениями пикселей из image_a, но оставляя другие пиксели без изменений. Мой код:

from __future__ import print_function
import numpy as np 
import cv2

image_a = cv2.imread("old_frame.png")
image_b = cv2.imread("new_frame.png")
cv2.imshow("image_a", image_a)
cv2.imshow("image_b", image_b)
transp_color = (0, 16, 8)
new_image = np.where(image_b == transp_color, image_a, image_b)
cv2.imshow("new_image", new_image)
cv2.waitKey()

old_frame.png new_frame.png new_image.png

Попытка решить эту проблему с помощью np.where приводит к неправильным цветам в результирующем изображении, как показано выше на 3-м рисунке. Так есть идеи, как это решить?

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

ОК, наконец-то нашел решение сам, вот код для этого:

import numpy as np
import cv2

image_a = cv2.imread("old_frame.png")
image_b = cv2.imread("new_frame.png")
cv2.imshow("image_a", image_a)
cv2.imshow("image_b", image_b)
transp_color = (0, 16, 8)[::-1]
channels = 3
f = np.all((image_b==transp_color), axis=-1)
flattened_image = np.reshape(image_b, (image_b.shape[0]*image_b.shape[1], channels))
old_flattened_image = np.reshape(image_a, (image_a.shape[0]*image_a.shape[1], channels))
f = np.reshape(f, (image_a.shape[0]*image_a.shape[1], 1))
np_image = np.array([old_flattened_image[i] if j else flattened_image[i] for i, j in enumerate(f)])
new_image = np.reshape(np_image, (image_a.shape[0], image_a.shape[1], channels))

# new_image = np.where(image_b == transp_color, image_a, image_b)

cv2.imshow("new_image", new_image)
cv2.waitKey()
0 голосов
/ 26 апреля 2019

Выражение image_b == transp_color приведет к массиву логических значений NxMx3. Это то, на что будет действовать np.where. Если я правильно понимаю ваш вопрос, самое простое решение - превратить это выражение в np.all(image_b == transp_color, axis=-1, keepdims=True). Это вернет массив логических значений NxMx1; который np.where будет транслироваться по цветному каналу, так что вы выбираете пиксель из изображения A или B.

...