Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting Numpy Array to OpenCV Array

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?

like image 664
Cerin Avatar asked Sep 28 '11 18:09

Cerin


People also ask

Does OpenCV work with NumPy array?

OpenCV is the most popular computer vision library and has a wide range of features. It doesn't have its own internal storage format for images, instead, it uses NumPy arrays. The common scenario for using this library is when you need to convert an image from Pillow to NumPy so that you can work with it using OpenCV.

Can you convert NumPy array to list in Python?

We can use NumPy np. array tolist() function to convert an array to a list. If the array is multi-dimensional, a nested list is returned. For a one-dimensional array, a list with the array elements is returned.


2 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:

  1. np.uint32 data type is not supported by OpenCV (it supports uint8, int8, uint16, int16, int32, float32, float64)
  2. cv.CvtColor can't handle numpy arrays so both arguments has to be converted to OpenCV type. cv.fromarray do this conversion.
  3. Both arguments of cv.CvtColor must 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) 
like image 112
Andrey Kamaev Avatar answered Sep 20 '22 13:09

Andrey Kamaev


This 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) 
like image 45
Mel Avatar answered Sep 18 '22 13:09

Mel