如何使用Opencv 2.4将Python的Numpy数组转换为RGB图像?

79

我已经搜索了类似的问题,但没有找到有用的东西,因为大多数解决方案使用旧版本的OpenCV。

我有一个3D numpy数组,并希望使用OpenCV(cv2)将其显示和/或保存为BGR图像。

举个简单的例子,假设我有:

import numpy, cv2
b = numpy.zeros([5,5,3])

b[:,:,0] = numpy.ones([5,5])*64
b[:,:,1] = numpy.ones([5,5])*128
b[:,:,2] = numpy.ones([5,5])*192

我想做的是将 b 保存并以类似以下方式显示为彩色图像:

cv2.imwrite('color_img.jpg', b)
cv2.imshow('Color image', b)
cv2.waitKey(0)
cv2.destroyAllWindows()

这个不起作用,可能是因为变量b的数据类型不正确,但是我经过大量搜索后,无法弄清如何将其更改为正确的数据类型。如果您能提供任何提示,那将不胜感激!


2
感谢您的评论@beaker!然而,那个问题在于发布者忘记在imshow()中添加一个参数。我的问题是imshow/ imwrite不会接受上面创建的numpy数组。 - Gillespie
你想把它保存为BGR还是RGB?标题和问题都有。 - jmunsch
@jmanring220 是的,但答案仍然展示了如何将numpy数组转换为mat。 - beaker
7个回答

56

不需要将NumPy数组转换为Mat,因为OpenCV的cv2模块可以接受NumPy数组。 唯一需要注意的是{0,1}映射到{0,255},而NumPy数组中任何大于1的值都等于255。因此,您应该在代码中除以255,如下所示。

img = numpy.zeros([5,5,3])

img[:,:,0] = numpy.ones([5,5])*64/255.0
img[:,:,1] = numpy.ones([5,5])*128/255.0
img[:,:,2] = numpy.ones([5,5])*192/255.0

cv2.imwrite('color_img.jpg', img)
cv2.imshow("image", img)
cv2.waitKey()

请问您能否解释一下为什么我们要乘以64、128和192吗? - Shubh Patni
2
哦,我明白了,我认为那只是应该在RGB位置中的值。 - Shubh Patni
如果有人需要反转颜色通道:cv2.imshow("color_img.jpg", input[..., ::-1] * 255) - LC117
非常清晰明了!对我很有帮助。 - lam vu Nguyen

25

8
在scipy 0.18.0中似乎不存在这个。 - Alex Kreimer
@AlexKreimer:http://docs.scipy.org/doc/scipy-0.18.0/reference/generated/scipy.misc.toimage.html - Martin Thoma
5
这个问题是关于使用OpenCV的方法的。 - M. Doosti Lakhani
2
是的。而且我的回答仍然对9个人有用。 - Martin Thoma
这实际上是我正在寻找的,我有一个来自opencv的numpy数组,我想在pysimpleui中显示它,其中需要一个适当的图像。 - kirhgoff

12

下面的图片 c、d、e 和 f 显示了色彩空间转换,它们也恰好是 numpy 数组 <type 'numpy.ndarray'>

import numpy, cv2
def show_pic(p):
        ''' use esc to see the results'''
        print(type(p))
        cv2.imshow('Color image', p)
        while True:
            k = cv2.waitKey(0) & 0xFF
            if k == 27: break 
        return
        cv2.destroyAllWindows()

b = numpy.zeros([200,200,3])

b[:,:,0] = numpy.ones([200,200])*255
b[:,:,1] = numpy.ones([200,200])*255
b[:,:,2] = numpy.ones([200,200])*0
cv2.imwrite('color_img.jpg', b)


c = cv2.imread('color_img.jpg', 1)
c = cv2.cvtColor(c, cv2.COLOR_BGR2RGB)

d = cv2.imread('color_img.jpg', 1)
d = cv2.cvtColor(c, cv2.COLOR_RGB2BGR)

e = cv2.imread('color_img.jpg', -1)
e = cv2.cvtColor(c, cv2.COLOR_BGR2RGB)

f = cv2.imread('color_img.jpg', -1)
f = cv2.cvtColor(c, cv2.COLOR_RGB2BGR)


pictures = [d, c, f, e]

for p in pictures:
        show_pic(p)
# show the matrix
print(c)
print(c.shape)

更多信息请参见此处:http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor

或者你可以:

img = numpy.zeros([200,200,3])

img[:,:,0] = numpy.ones([200,200])*255
img[:,:,1] = numpy.ones([200,200])*255
img[:,:,2] = numpy.ones([200,200])*0

r,g,b = cv2.split(img)
img_bgr = cv2.merge([b,g,r])

8
这是因为cv2使用了numpy的"uint8"类型。因此,在创建数组时应定义类型。

可以参考以下方式:

import numpy
import cv2

b = numpy.zeros([5,5,3], dtype=numpy.uint8)
b[:,:,0] = numpy.ones([5,5])*64
b[:,:,1] = numpy.ones([5,5])*128
b[:,:,2] = numpy.ones([5,5])*192

6
如果其他人想要将黑色图像作为背景显示,可以使用以下代码(例如,500x500像素大小):

import cv2
import numpy as np

black_screen  = np.zeros([500,500,3])
cv2.imshow("Simple_black", black_screen)
cv2.waitKey(0)

4

您的图片尺寸太小,肉眼无法观察,请至少使用50x50。

import cv2 as cv
import numpy as np

black_screen = np.zeros([50,50,3])

black_screen[:, :, 2] = np.ones([50,50])*64/255.0
cv.imshow("Simple_black", black_screen)
cv.waitKey(0)
cv.displayAllWindows()

0
img = np.ones((1080, 720, 3), dtype=np.uint8) * 255

创建白色图像,您必须使用的dtypenp.uint8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接