Преобразование массива Numpy в массив OpenCV
Я пытаюсь преобразовать массив 2D Numpy, представляющий черно-белое изображение, в 3-канальный массив OpenCV (т.е. изображение RGB).
На основе примеры кода и документы я ' m пытается сделать это через 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
Что я делаю неправильно?
Ответы
Ответ 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)
Краткое объяснение:
-
np.uint32
тип данных не поддерживается OpenCV (он поддерживает uint8
, int8
, uint16
, int16
, int32
, float32
, float64
)
-
cv.CvtColor
не может обрабатывать массивы numpy, поэтому оба аргумента должны быть преобразованы в тип OpenCV. cv.fromarray
выполните это преобразование.
- Оба аргумента
cv.CvtColor
должны иметь одинаковую глубину. Поэтому я изменил исходный тип на 32-битный float, чтобы он соответствовал ddestination.
Также я рекомендую использовать более новую версию API-интерфейса OpenCV python, поскольку в качестве основного типа данных используется массив numpy:
import numpy as np, cv2
vis = np.zeros((384, 836), np.float32)
vis2 = cv2.cvtColor(vis, cv2.COLOR_GRAY2BGR)
Ответ 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)