将 Numpy 数组转换为 OpenCV 数组

Posted

技术标签:

【中文标题】将 Numpy 数组转换为 OpenCV 数组【英文标题】:Converting Numpy Array to OpenCV Array 【发布时间】:2011-11-27 02:23:27 【问题描述】:

我正在尝试将表示黑白图像的 2D Numpy 数组转换为 3 通道 OpenCV 数组(即 RGB 图像)。

基于 code samples 和 the docs 我正在尝试通过 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 Error: Image step is wrong () in cvSetData。我注意到代码示例使用了不同的数据类型:请参阅vis = np.zeros((max(h1, h2), w1+w2), np.uint8) 【参考方案1】:

您的代码可以修复如下:

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)

简短说明:

    OpenCV 不支持np.uint32 数据类型(它支持uint8int8uint16int16int32float32float64cv.CvtColor 无法处理 numpy 数组,因此两个参数都必须转换为 OpenCV 类型。 cv.fromarray 进行此转换。 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)

【讨论】:

感谢您的帮助。就是这样。 只需更新 OpenCV 的较新版本不再需要此类转换,因为 OpenCV 数组是 NumPy 数组。【参考方案2】:

这对我有用...

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)

【讨论】:

【参考方案3】:

最简单的解决方案是使用 Pillow 库:

from PIL import Image

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

您可以将其用作图像。

【讨论】:

以上是关于将 Numpy 数组转换为 OpenCV 数组的主要内容,如果未能解决你的问题,请参考以下文章

Python - 使用 OpenCV 将字节图像转换为 NumPy 数组

将 numpy 切片转换为 Opencv c++ Mat

将CV2 numpy数组转换为QImage时如何配置颜色?

当使用 OpenCV 将 B/W 图像读取为 Numpy 数组时,我得到的结果与读取为图像不同

将2d数组转换为图像

将 numpy 数组转换为 CSV 字符串,将 CSV 字符串转换回 numpy 数组