将Numpy数组转换为OpenCV数组

54 投票
3 回答
206966 浏览
提问于 2025-04-17 03:17

我正在尝试把一个二维的Numpy数组(它代表了一张黑白图片)转换成一个三通道的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

我哪里做错了呢?

3 个回答

-1

最简单的解决办法就是使用Pillow这个库:

from PIL import Image

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

然后你就可以把它当作一张图片来使用。

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)
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. np.uint32 这种数据类型在 OpenCV 中不被支持(它支持 uint8, int8, uint16, int16, int32, float32, float64
  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)

撰写回答