转换为 uint8 时 CV2 不显示颜色
CV2 not displaying colors when converting to uint8
我有一个 python 列表,其中包含表示为 int32 的 PNG 图像的 RGBA 数据,它是从 Java 套接字服务器发送过来的。
此数据作为 numpy 数组的示例输出,没有任何转换:
[[-12763847 -12763847 -12763847 ... -5590160 -12039396 -12434915]
[-12763847 -12763847 -12763847 ... -6643102 -12828909 -12830184]
[-12763847 -12763847 -12763847 ... -8419763 -13487094 -12435167]]
CV2 当然接受 uint8 作为数据类型(显示为 int32 显示黑屏),所以我将我的列表转换为带有 dtype = np.uint8
的 numpy 数组,如下所示:
image_data = np.array(data_list, dtype = np.uint8)
此示例输出:
[[ 57 57 57 ... 112 28 29]
[ 57 57 57 ... 98 19 24]
[ 57 57 57 ... 77 10 33]]
但是,当我使用
显示图像时
cv2.imshow("Image", image_data)
我得到 window 显示图像,但是是灰度的;它缺少颜色。
如何防止颜色被忽略?
要使用 cv2 输出彩色图像,您需要图像的形状为 (x,y,3)
,最后一个轴是颜色。
由于您的数据是 RGBA 的 int32 表示,我假设每个数字实际上包含 4 个不同的数字,其中前 2 个字节是红色的 uint8,第二个是绿色,第三个是蓝色,最后一个是 alpha:(0000 0001, 0000 0010, 0000 0100,0000 1000)
在此示例中,r 为 1,g 为 2,b 为 4,alpha 为 8。
您需要将这 8 个字节提取到单独的颜色中。
此外,请记住 cv2 颜色 space 是 BGR
而不是 RGB
,因此转换后必须切换通道。
希望这能帮助您了解如何从 32 位值中提取红色、绿色和蓝色通道。我从你数组的第一行开始。
im=np.array([-12763847,-12763847,-12763847,-5590160,-12039396,-12434915],dtype=np.int32)
R = ((im & 0xff).astype(np.uint8)
# array([ 57, 57, 57, 112, 28, 29], dtype=uint8)
G = ((im>>8) & 0xff).astype(np.uint8)
# array([ 61, 61, 61, 179, 75, 66], dtype=uint8)
B = ((im>>16) & 0xff).astype(np.uint8)
# array([ 61, 61, 61, 170, 72, 66], dtype=uint8)
如果这些值看起来正确,您应该能够将它们合并到彩色图像中:
img = cv2.merge((B,G,R))
请记住,OpenCV 使用 BGR
通道排序而不是更传统的 RGB
。
您的 32 位数字中的字节顺序可能与我上面猜测的不同。最简单的测试方法是在相机前放一张红卡,看看有什么通过,然后是绿卡,然后是蓝卡。四个通道 (R,G,B,A) 应由以下给出,但这可能是实验的问题:
(im ) & 0xff
(im>>8 ) & 0xff
(im>>16) & 0xff
(im>>24) & 0xff
我有一个 python 列表,其中包含表示为 int32 的 PNG 图像的 RGBA 数据,它是从 Java 套接字服务器发送过来的。
此数据作为 numpy 数组的示例输出,没有任何转换:
[[-12763847 -12763847 -12763847 ... -5590160 -12039396 -12434915]
[-12763847 -12763847 -12763847 ... -6643102 -12828909 -12830184]
[-12763847 -12763847 -12763847 ... -8419763 -13487094 -12435167]]
CV2 当然接受 uint8 作为数据类型(显示为 int32 显示黑屏),所以我将我的列表转换为带有 dtype = np.uint8
的 numpy 数组,如下所示:
image_data = np.array(data_list, dtype = np.uint8)
此示例输出:
[[ 57 57 57 ... 112 28 29]
[ 57 57 57 ... 98 19 24]
[ 57 57 57 ... 77 10 33]]
但是,当我使用
显示图像时cv2.imshow("Image", image_data)
我得到 window 显示图像,但是是灰度的;它缺少颜色。
如何防止颜色被忽略?
要使用 cv2 输出彩色图像,您需要图像的形状为 (x,y,3)
,最后一个轴是颜色。
由于您的数据是 RGBA 的 int32 表示,我假设每个数字实际上包含 4 个不同的数字,其中前 2 个字节是红色的 uint8,第二个是绿色,第三个是蓝色,最后一个是 alpha:(0000 0001, 0000 0010, 0000 0100,0000 1000)
在此示例中,r 为 1,g 为 2,b 为 4,alpha 为 8。
您需要将这 8 个字节提取到单独的颜色中。
此外,请记住 cv2 颜色 space 是 BGR
而不是 RGB
,因此转换后必须切换通道。
希望这能帮助您了解如何从 32 位值中提取红色、绿色和蓝色通道。我从你数组的第一行开始。
im=np.array([-12763847,-12763847,-12763847,-5590160,-12039396,-12434915],dtype=np.int32)
R = ((im & 0xff).astype(np.uint8)
# array([ 57, 57, 57, 112, 28, 29], dtype=uint8)
G = ((im>>8) & 0xff).astype(np.uint8)
# array([ 61, 61, 61, 179, 75, 66], dtype=uint8)
B = ((im>>16) & 0xff).astype(np.uint8)
# array([ 61, 61, 61, 170, 72, 66], dtype=uint8)
如果这些值看起来正确,您应该能够将它们合并到彩色图像中:
img = cv2.merge((B,G,R))
请记住,OpenCV 使用 BGR
通道排序而不是更传统的 RGB
。
您的 32 位数字中的字节顺序可能与我上面猜测的不同。最简单的测试方法是在相机前放一张红卡,看看有什么通过,然后是绿卡,然后是蓝卡。四个通道 (R,G,B,A) 应由以下给出,但这可能是实验的问题:
(im ) & 0xff
(im>>8 ) & 0xff
(im>>16) & 0xff
(im>>24) & 0xff