本文主要介绍Matlab与C/C++混合编程,并给出Matlab调用Opencv的具体实例。参考资料在文末给出。
1. mexFunction
在Matlab与C/C++混合编程中,mexFunction必不可少。其基本形式为:
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs)1
其中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' }; %------------------------------------------------------------------- %% compilingfor 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'); %-------------------------------------------------------------------123456789101112131415161718192021222324252627282930313233343536373839404142
例如,我电脑里的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' };12345678910
发货快
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; }123456789101112131415161718192021222324252627
然后,在同级目录下放一张lena.jpg,然后mex test.cpp成功生成test.mexw64之后,直接在matlab里输入test(‘lena.jpg’)发现却报如下错误 “Invalid MEX-file ‘F:\MC\test.mexw64’: 找不到指定的模块。”问题出在你没有把相应的dll放到同级目录下。因为我至多用到了3个lib,我只需要将对应的dll拷到目录,如下图:
这时候再直接运行test(‘lena.jpg’)即可得到结果如下图:
4. 参考资料
http://blog.sina.com.cn/s/blog_492dbb6b0100arl2.html
http://www.cnblogs.com/lukylu/p/3966871.html