как преобразовать OpenCV cvMat обратно в ndarray в numpy? - PullRequest
10 голосов
/ 23 апреля 2011

Я следую коду в кулинарной книге OpenCV для интерфейса Python, чтобы преобразовать cvMat в массив numpy:

mat = cv.CreateMat(3,5,cv.CV_32FC1)
cv.Set(mat,7)
a = np.asarray(mat)

, но с OpenCV 2.1 на моем ПК это не работает.Результатом a здесь является массив объектов, при использовании "print a" не печатается весь элемент в a , только print <cvmat(type=42424005 rows=3 cols=5 step=20 )>.как полностью преобразовать объект OpenCV Mat в исходный numpy.ndarray объект.

Ответы [ 3 ]

9 голосов
/ 04 мая 2011

Попробуйте добавить [:,:] к матрице (т. Е. Использовать mat[:,:] вместо mat) при вызове np.asarray - это также позволит asarray работать с изображениями.

Ваш пример:

>>> import cv
>>> import numpy as np
>>> mat = cv.CreateMat( 3 , 5 , cv.CV_32FC1 )
>>> cv.Set( mat , 7 )
>>> a = np.asarray( mat[:,:] )
>>> a
array([[ 7.,  7.,  7.,  7.,  7.],
       [ 7.,  7.,  7.,  7.,  7.],
       [ 7.,  7.,  7.,  7.,  7.]], dtype=float32)

А для изображения:

>>> im = cv.CreateImage( ( 5 , 5 ) , 8 , 1 )
>>> cv.Set( im , 100 )
>>> im_array = np.asarray( im )
>>> im_array
array(<iplimage(nChannels=1 width=5 height=5 widthStep=8 )>, dtype=object)
>>> im_array = np.asarray( im[:,:] )
>>> im_array
array([[100, 100, 100, 100, 100],
       [100, 100, 100, 100, 100],
       [100, 100, 100, 100, 100],
       [100, 100, 100, 100, 100],
       [100, 100, 100, 100, 100]], dtype=uint8)
2 голосов
/ 25 апреля 2011

Для версии 2.1 OpenCV, если вам нужно поделиться памятью и если вас не волнует программирование на C и SWIG-обертывание, вы можете попробовать это решение, которое я использовал для некоторыхвремя:

CvMat * npymat_as_cvmat_32f(float * npymat_float, int rows, int cols)
{
  CvMat * cvmat;

  cvmat = cvCreateMatHeader(rows, cols, CV_32FC1);
  cvSetData(cvmat, npymat_float, cols * sizeof(float));

  return cvmat;
}

Создайте заголовок, например, mat_conversion.h:

/* npymat_as_cvmat_32f
 * 
 * Create an OpenCV CvMat that shared its data with the input NumPy double array
 */
CvMat * npymat_as_cvmat_32f(float * npymat_float, int rows, int cols);

и файл интерфейса (numpy_meets_opencv.i):

/* numpy_meets_opencv */
%module numpy_meets_opencv

%{
#define SWIG_FILE_WITH_INIT
#include <cv.h>
#include "mat_conversion.h"
%}

%include "numpy.i"

%init %{
import_array();
%}

%apply (float* INPLACE_ARRAY2, int DIM1, int DIM2) {(float* npymat_float, int rows, int cols)};

%include "mat_conversion.h"

Компиляция:

numpy_meets_opencv: numpy_meets_opencv.i mat_conversion.c
        swig -python -classic numpy_meets_opencv.i
        $(CC) $(NPY_CFLAGS) -fPIC -fno-stack-protector -c mat_conversion.c `pkg-config --cflags $(PKGS)`        
        $(CC) $(NPY_CFLAGS) -fPIC -fno-stack-protector -c numpy_meets_opencv_wrap.c `pkg-config --cflags $(PKGS)`
        ld -shared mat_conversion.o numpy_meets_opencv_wrap.o `pkg-config --libs $(PKGS)` -o _numpy_meets_opencv.so

Наконец, вы можете делать свои вещи:

In [1]: import numpy_meets_opencv as npyocv
In [2]: import opencv as cv
In [4]: import numpy as npy
In [12]: Inpy = npy.zeros((5,5), dtype=npy.float32)
In [13]: Iocv = npyocv.npymat_as_cvmat_32f(Inpy)
In [14]: Inpy
Out[14]: 
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]], dtype=float32)
In [15]: Iocv
Out[15]: <opencv.cv.CvMat; proxy of <Swig Object of type 'CvMat *' at 0x30e6ed0> >
In [17]: cv.cvSetReal2D(Iocv, 3,3, 255)
In [18]: Inpy
Out[18]: 
array([[   0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,    0.,    0.],
       [   0.,    0.,    0.,  255.,    0.],
       [   0.,    0.,    0.,    0.,    0.]], dtype=float32)
2 голосов
/ 23 апреля 2011

Вы правы, пример поваренной книги у меня тоже не работает, и я получаю тот же вывод, что и у вас (win xp, python 2.6.6, opencv 2.1., Numpy 1.5.1).

ВозможноВы можете использовать что-то похожее на:

>>> mat = cv.CreateMat(3,5,cv.CV_32FC1)
>>> cv.Set(mat,7)
>>> mylist = [[mat[i,j] for i in range(3)] for j in range(5)]
>>> ar = np.array(mylist)
>>> ar
array([[ 7.,  7.,  7.],
       [ 7.,  7.,  7.],
       [ 7.,  7.,  7.],
       [ 7.,  7.,  7.],
       [ 7.,  7.,  7.]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...