Python OpenCV:反转 numpy 图像数组中的颜色
Python OpenCV : inverting colors in a numpy image array
我一直在尝试操纵一个非常简单的 8 x 8 图像(变量 "abc"
)的颜色(BGR 值),但是当我尝试查看具有反转颜色的新图像(变量 "target"
),我得到的只是一张黑色图片。谁能帮帮我?
我什至尝试在更改代码后检查两个数组是否完全匹配,以尝试一次复制一个像素的图像,条件等同于 True
但图片保持黑色。
我已经发布了下面的代码:
import cv2
import numpy as np
abc = cv2.imread("new.png")
(x1, y1) = abc.shape[:2]
a1 = []
a2 = []
a3 = []
for i in range(x1):
for d in range(y1):
for g in range(3):
if g == 0:
a1.append(abc[i, d, g])
elif g == 1:
a2.append(abc[i, d, g])
elif g == 2:
a3.append(abc[i, d, g])
u = 0
target = np.empty(shape=(x1, y1, 3), dtype="int32")
for i in range(x1):
for d in range(y1):
target[i, d, 1] = a2[u]
target[i, d, 2] = a3[u]
target[i, d, 0] = a1[u]
u = u + 1
if (abc == target).all():
print "equal/match"
cv2.imshow('target', target)
cv2.waitKey(0)
cv2.destroyAllWindows()
我想向您指出 cv2.imshow
的文档:http://docs.opencv.org/modules/highgui/doc/user_interface.html#imshow
阅读注释中关于您尝试显示的图像类型的内容:
- 如果图像是 8 位无符号的,则按原样显示。
- 如果图片是16位无符号或32位整数,像素点除以256,即取值范围
[0,255*256]
映射到[0,255]
.
- 如果图片是32位浮点数,则像素值乘以255,即取值范围
[0,1]
映射到[0,255]
.
你的情况是第二点。您正在做的是输入图像最有可能是无符号 8 位整数开头。因为您创建了一个 int
类型的输出图像(实际上是 int32
),这相当于一个 32 位整数类型的图像,所以发生的是所有值都被除以256. 对于 8 位无符号整数类型,所有值都在 0 到 255 之间,因此除以 256 会使所有像素 black(即 [0,255] / 256 --> [0,0]
假设整数师)。
要解决此问题,您需要为输出正确创建正确的图像类型。在你的情况下,我假设你的输入数据类型是 uint8
,考虑到我所看到的情况,这是最有意义的,所以只需更改 target
以便 dtype
是 uint8
:
target = np.empty(shape=(x1, y1, 3), dtype=np.uint8)
小注
通过切片进入三维空间,您可以非常有效地完成您想要的。
因此,target
可以非常简单地是以下内容,而无需使用任何 for
循环或临时列表来复制空间坐标元组:
target = abc[:,:,[1,2,0]]
额外的好处是 target
将保持与 abc
相同的数据类型。在此处阅读 numpy
索引和切片:http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html
我一直在尝试操纵一个非常简单的 8 x 8 图像(变量 "abc"
)的颜色(BGR 值),但是当我尝试查看具有反转颜色的新图像(变量 "target"
),我得到的只是一张黑色图片。谁能帮帮我?
我什至尝试在更改代码后检查两个数组是否完全匹配,以尝试一次复制一个像素的图像,条件等同于 True
但图片保持黑色。
我已经发布了下面的代码:
import cv2
import numpy as np
abc = cv2.imread("new.png")
(x1, y1) = abc.shape[:2]
a1 = []
a2 = []
a3 = []
for i in range(x1):
for d in range(y1):
for g in range(3):
if g == 0:
a1.append(abc[i, d, g])
elif g == 1:
a2.append(abc[i, d, g])
elif g == 2:
a3.append(abc[i, d, g])
u = 0
target = np.empty(shape=(x1, y1, 3), dtype="int32")
for i in range(x1):
for d in range(y1):
target[i, d, 1] = a2[u]
target[i, d, 2] = a3[u]
target[i, d, 0] = a1[u]
u = u + 1
if (abc == target).all():
print "equal/match"
cv2.imshow('target', target)
cv2.waitKey(0)
cv2.destroyAllWindows()
我想向您指出 cv2.imshow
的文档:http://docs.opencv.org/modules/highgui/doc/user_interface.html#imshow
阅读注释中关于您尝试显示的图像类型的内容:
- 如果图像是 8 位无符号的,则按原样显示。
- 如果图片是16位无符号或32位整数,像素点除以256,即取值范围
[0,255*256]
映射到[0,255]
. - 如果图片是32位浮点数,则像素值乘以255,即取值范围
[0,1]
映射到[0,255]
.
你的情况是第二点。您正在做的是输入图像最有可能是无符号 8 位整数开头。因为您创建了一个 int
类型的输出图像(实际上是 int32
),这相当于一个 32 位整数类型的图像,所以发生的是所有值都被除以256. 对于 8 位无符号整数类型,所有值都在 0 到 255 之间,因此除以 256 会使所有像素 black(即 [0,255] / 256 --> [0,0]
假设整数师)。
要解决此问题,您需要为输出正确创建正确的图像类型。在你的情况下,我假设你的输入数据类型是 uint8
,考虑到我所看到的情况,这是最有意义的,所以只需更改 target
以便 dtype
是 uint8
:
target = np.empty(shape=(x1, y1, 3), dtype=np.uint8)
小注
通过切片进入三维空间,您可以非常有效地完成您想要的。
因此,target
可以非常简单地是以下内容,而无需使用任何 for
循环或临时列表来复制空间坐标元组:
target = abc[:,:,[1,2,0]]
额外的好处是 target
将保持与 abc
相同的数据类型。在此处阅读 numpy
索引和切片:http://docs.scipy.org/doc/numpy/reference/arrays.indexing.html