I'm trying to convert a 2D Numpy array, representing a black-and-white image, into a 3-channel OpenCV array (i.e. an RGB image).
Based on code samples and the docs I'm attempting to do this via Python like:
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) However, the call to CvtColor() is throwing the following cpp-level Exception:
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 What am I doing wrong?
13 Answers
Your code can be fixed as follows:
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) Short explanation:
np.uint32data type is not supported by OpenCV (it supportsuint8,int8,uint16,int16,int32,float32,float64)cv.CvtColorcan't handle numpy arrays so both arguments has to be converted to OpenCV type.cv.fromarraydo this conversion.- Both arguments of
cv.CvtColormust have the same depth. So I've changed source type to 32bit float to match the ddestination.
Also I recommend you use newer version of OpenCV python API because it uses numpy arrays as primary data type:
import numpy as np, cv2 vis = np.zeros((384, 836), np.float32) vis2 = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR) 2This is what worked for me...
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) The simplest solution would be to use Pillow lib:
from PIL import Image image = Image.fromarray(<your_numpy_array>.astype(np.uint8)) And you can use it as an image.