将NumPy数组转换为OpenCV数组

53

我想将一个表示黑白图像的2D Numpy数组转换为一个3通道的OpenCV数组(即RGB图像)。

根据代码示例文档,我试图通过Python实现以下操作:

import numpy as np, cv
vis = np.zeros((384, 836), np.uint32)
h,w = vis.shape
vis2 = cv.CreateMat(h, w, cv.CV_32FC3)
cv.CvtColor(vis, vis2, cv.CV_GRAY2BGR)

然而,对CvtColor()的调用会抛出以下cpp级别的异常:

OpenCV Error: Image step is wrong () in cvSetData, file /build/buildd/opencv-2.1.0/src/cxcore/cxarray.cpp, line 902
terminate called after throwing an instance of 'cv::Exception'
  what():  /build/buildd/opencv-2.1.0/src/cxcore/cxarray.cpp:902: error: (-13)  in function cvSetData

Aborted

我做错了什么?

CvtColor的文档中可以看到:“src-源图像,8位无符号,16位无符号(CV_16UC...)或单精度浮点数”。我注意到你的numpy数组是np.uint32。这可能解释了OpenCV错误:cvSetData中的图像步骤错误()。我注意到代码示例使用了不同的数据类型:请参见vis = np.zeros((max(h1, h2), w1+w2), np.uint8) - Steven Rumbalski
3个回答

56

你的代码可以按照以下方式修复:

import numpy as np, cv
vis = np.zeros((384, 836), np.float32)
h,w = vis.shape
vis2 = cv.CreateMat(h, w, cv.CV_32FC3)
vis0 = cv.fromarray(vis)
cv.CvtColor(vis0, vis2, cv.CV_GRAY2BGR)

简要说明:

  1. OpenCV不支持np.uint32数据类型(它支持uint8int8uint16int16int32float32float64)。
  2. cv.CvtColor无法处理numpy数组,因此两个参数都必须转换为OpenCV类型。cv.fromarray完成这个转换。
  3. cv.CvtColor的两个参数必须具有相同的深度。所以我已经将源类型更改为32位浮点数以匹配目标类型。

此外,我建议您使用更新的OpenCV Python API,因为它将numpy数组作为主要数据类型:

import numpy as np, cv2
vis = np.zeros((384, 836), np.float32)
vis2 = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)

2
只需更新OpenCV的新版本,就不再需要进行此类转换,因为OpenCV数组是NumPy数组。 - Chris Tang

8
这是对我有效的解决方案...
import cv2
import numpy as np

#Created an image (really an ndarray) with three channels 
new_image = np.ndarray((3, num_rows, num_cols), dtype=int)

#Did manipulations for my project where my array values went way over 255
#Eventually returned numbers to between 0 and 255

#Converted the datatype to np.uint8
new_image = new_image.astype(np.uint8)

#Separated the channels in my new image
new_image_red, new_image_green, new_image_blue = new_image

#Stacked the channels
new_rgb = np.dstack([new_image_red, new_image_green, new_image_blue])

#Displayed the image
cv2.imshow("WindowNameHere", new_rgbrgb)
cv2.waitKey(0)

-1
最简单的解决方案是使用Pillow库:
from PIL import Image

image = Image.fromarray(<your_numpy_array>.astype(np.uint8))

你可以将其用作图像。

2
OP要求将表示黑白图像的2D Numpy数组转换为3通道OpenCV数组。您的解决方案并未回答该问题。 - Eljas Hyyrynen

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