使用np.where在numpy数组中查找唯一元组

问题描述 投票:0回答:2

我想在np.where中找到一个numpy数组中的独特颜色元组。到目前为止我的代码是:

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]]

?

编辑:

好的,所以当前的问题是在python中编写一个GIF解码器。我有一个名为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张图片中所示。那么任何想法如何解决这个问题?

arrays numpy tuples unique where
2个回答
0
投票

表达式image_b == transp_color将产生NxMx3的布尔数组。这就是np.where也会采取行动的原因。如果我正确理解你的问题,这里最简单的解决方案是将表达式转换为np.all(image_b == transp_color, axis=-1, keepdims=True)。这将返回一个NxMx1阵列的布尔值; np.where将通过颜色通道进行广播,以便从图像A或B中选择一个像素。


0
投票

好的,最后我自己找到了解决方案,这里是执行此操作的代码:

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()
© www.soinside.com 2019 - 2024. All rights reserved.