2012-06-30 114 views
2

我通过Matlab使用OpenCV检测视频中的人脸,然后使用Matlab进行一些处理。目前,我在视频的IplImage结构框架(通过cvQueryFrame查询)面临检测。我将每个查询的帧保存为jpg,然后使用面部坐标获取所需处理的ROI。请参阅下面概述的代码部分。在Matlab中将Iplimage转换为矩阵或阵列

% After reading in frame from video.. 
for i=1:size 
    img = calllib('highgui210','cvQueryFrame',cvCapture); 
    calllib('cxcore210','cvFlip',img,img,1); 
    calllib('highgui210', 'cvSaveImage', 'ThisFrame.jpg', img, ptr); 
% Rest of the processing comes here.. 

既然如此,感觉,应该有一个“的IplImage”图像转换为在Matlab矩阵或阵列的更容易,更-粗方式。这有可能吗?如果是的话,这是如何完成的?

在这个方向上的一些指针将不胜感激!

回答

2

尝试mexing下面的代码:

/* 
* Usage: 
* img = IplImage2mxArray(cvImgPtr, releaseFlag); 
*/ 
void mexFunction(int nout, mxArray* pout[], int nin, const mxArray* pin[]) { 
    if (nin != 2) 
     mexErrMsgTxt("wrong number of inputs"); 
    if (nout != 1) 
     mexErrMsgTxt("wrong number of outputs"); 
    IplImage* cvImg = (IplImage*)mxGetData(pin[0]); // get the pointer 
    // allocate the output 
    mwSize imgDims[3] = {cvImg->height, cvImg->width, cvImg->nChannels}; 
    pout[0] = mxCreateNumericArray(3, imgDims, mxDOUBLE_CLASS, mxREAL); 
    if (pout[0] == NULL) 
     mexErrMsgTxt("out of memeory"); 
    double* imgP = mxGetPr(pout[0]); 
    double divVal = pow(2.0, cvImg->depth) - 1; 
    double releaseFlag = mxGetScalar(pin[1]); 
    for (int x = 0 ; x < cvImg->width; x++) { 
     for (int y = 0 ; y < cvImg->height; y++) { 
      CvScalar s = cvGet2D(cvImg, y, x); 
      for (int c = 0; c < cvImg->nChannels; c++) { 
       imgP[ y + x * cvImg->height + c * cvImg->height * cvImg->width ] = s.val[c]/divVal; 
      } 
     } 
    } 
    if (releaseFlag != 0) { 
     cvReleaseImage(&cvImg); 
    } 
} 

你会用一个函数(MEX)IplImage2mxArray结束了,用它在Matlab:

>> cvImg = calllib('highgui210','cvQueryFrame',cvCapture); 
>> img = IplImage2mxArray(cvImg, false); % no cvReleaseImage after cvQueryFrame 

由于内部OpenCV的申述的渠道img可能会被置换(RGB的BGR未读)。另请注意,img可能包含四个通道 - 一个额外的alpha通道。

-Shai