Matlab调用Opencv

本文主要介绍Matlab与C/C++混合编程,并给出Matlab调用Opencv的具体实例。参考资料在文末给出。
1. mexFunction
在Matlab与C/C++混合编程中,mexFunction必不可少。其基本形式为:

void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs)

其中nlhs表示输出参数的个数,plhs为指向输出参数的指针,nrhs表述输入参数的个数,prhs为指向输入参数的指针。例如,某个mexFunction最终保存的文件名为test.cpp,在mex test.cpp之后,使用[a,b]=test(c,d,e)即可调用mexFunction,有三个输入参数,也就是说nrhs=3,有两个输出参数,因此nlhs=2。更具体地,输入的三个参数c,d,e分别对应prhs[0]=c,prhs[1]=d,prhs[2]=e,输出为plhs[0]=a,plhs[1]=b.注意到plhs[i]和prhs[i]都是指向mxArray类型的指针,这个类型是在mex.h中定义的,具体细节先不谈,原因很简单,因为我也不太懂。
2. 配置Opencv
关于Opencv的配置网上说法不一。根据自身实践,下面的方法可以较为方便。写一个cppmake.m文件,根据个人情况的不同稍适修改即可完成配置。下面是一位博主的代码:

% This cppmake.m is for MATLAB
% Function: compile c++ files which rely on OpenCV for Matlab using mex
% Modified by Jessica
% Date    : 2014-9-10
% HomePage: http://www.cnblogs.com/lukylu/
% Email   : wanglu@innomotion.biz

% Matlab and C++ mixed programming(dependent on opencv library)
% First step(before exeuting this program): use "mex -setup" to choose your c/c++ compiler
clear all;

% Get the architecture of this computer
is_64bit = strcmp(computer,'MACI64') || strcmp(computer,'GLNXA64') || strcmp(computer,'PCWIN64');
%-------------------------------------------------------------------
%% The configuration of compiler
% You need to modify this configuration according to your own path of OpenCV  
% Notice: if your system is 64bit, your OpenCV must be 64bit! 
out_dir='./';  
CPPFLAGS = ' -O -DNDEBUG -I.\ -IF:\opencv\build\include -IF:\opencv\build\include\opencv -IF:\opencv\build\include\opencv2'; % your OpenCV "include" path  
LDFLAGS = ' -LF:\opencv\build\x86\vc10\lib'; % your OpenCV "lib" path
%LIBS = ' -lopencv_calib3d249d -lopencv_contrib249d -lopencv_core249d -lopencv_features2d249d -lopencv_flann249d -lopencv_gpu249d -lopencv_highgui249d -lopencv_imgproc249d -lopencv_legacy249d -lopencv_ml249d -lopencv_nonfree249d -lopencv_objdetect249d -lopencv_photo249d -lopencv_stitching249d -lopencv_ts249d -lopencv_video249d -lopencv_videostab249d';
LIBS = ' -lopencv_calib3d249 -lopencv_contrib249 -lopencv_core249 -lopencv_features2d249 -lopencv_flann249 -lopencv_gpu249 -lopencv_highgui249 -lopencv_imgproc249 -lopencv_legacy249 -lopencv_ml249 -lopencv_nonfree249 -lopencv_objdetect249 -lopencv_photo249 -lopencv_stitching249 -lopencv_ts249 -lopencv_video249 -lopencv_videostab249';
if is_64bit  
    CPPFLAGS = [CPPFLAGS ' -largeArrayDims'];  
end  

% add your files here!!
compile_files = {
    %the list of your code files which need to be compiled
    'ImageCalibration.cpp'
    };
%-------------------------------------------------------------------
%% compiling
for k = 1 : length(compile_files)  
    str = compile_files{k};  
    fprintf('compilation of: %s\n', str);  
    str = [str ' -outdir ' out_dir CPPFLAGS LDFLAGS LIBS];  
    args = regexp(str, '\s+', 'split');  
    mex(args{:});  
end 
fprintf('Congratulations, compilation successful!!!\n');
%-------------------------------------------------------------------

例如,我电脑里的opencv解压在F盘,我自己写的mexFunction保存位test.cpp,我只用到了三个lib,所以我只需要将上面的代码修改为:

CPPFLAGS = ' -O -DNDEBUG -I.\ -IF:\opencv\build\include -IF:\opencv\build\include\opencv -IF:\opencv\build\include\opencv2'; 
LDFLAGS = ' -LF:\opencv\build\x64\vc12\lib';                       
LIBS = '-lopencv_core249 -lopencv_highgui249 -lopencv_imgproc249 ';
if is_64bit  
    CPPFLAGS = [CPPFLAGS ' -largeArrayDims'];  
end  
compile_files = {
    'test.cpp'
    };

发货快
3. 实例
例如,我直接在网上找了一个代码放到test.cpp里面去,代码如下:

#include"mex.h"
#include"cv.h"
#include"highgui.h"
using namespace cv;
void mexFunction (int nlhs, mxArray *plhs[], // 输出参数个数,及输出参数数组
    int nrhs, const mxArray *prhs[]) // 输入参数个数,及输入参数数组

{
    char name[256];
    int buflens = mxGetNumberOfElements(prhs[0]);
    mxGetString(prhs[0], name, buflens+1);
     if(!mxIsChar(prhs[0]))
     {
        mexErrMsgTxt("First parameter must be string/n");
     }
    mexPrintf(name);
    IplImage * img = cvLoadImage(name, 1);
    if(img->imageData == NULL)
     {
        mexErrMsgTxt("Error in image/n");
     }
    cvNamedWindow("1",1);
    //imshow("1",mat);
    cvShowImage("1",img);
    cvWaitKey(0);
    return;
}

然后,在同级目录下放一张lena.jpg,然后mex test.cpp成功生成test.mexw64之后,直接在matlab里输入test(‘lena.jpg’)发现却报如下错误 “Invalid MEX-file ‘F:\MC\test.mexw64’: 找不到指定的模块。”问题出在你没有把相应的dll放到同级目录下。因为我至多用到了3个lib,我只需要将对应的dll拷到目录,如下图:
缺失的dll
这时候再直接运行test(‘lena.jpg’)即可得到结果如下图:
Matlab调用Opencv_第1张图片
4. 参考资料
http://blog.sina.com.cn/s/blog_492dbb6b0100arl2.html
http://www.cnblogs.com/lukylu/p/3966871.html

你可能感兴趣的:(MATLAB,C++)