本文主要介绍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拷到目录,如下图:
这时候再直接运行test(‘lena.jpg’)即可得到结果如下图:
4. 参考资料
http://blog.sina.com.cn/s/blog_492dbb6b0100arl2.html
http://www.cnblogs.com/lukylu/p/3966871.html