由于在实验中用到Matlab调用C++程序,而C++程序中又调用了OpenCV,所以用到了Matlab、C++、OpenCV混合编程。通过在网上查找资料,做实验,终于弄清楚了一些问题,特此记录下来,供以后参考使用。
系统环境:Windows 8.1 64位
C++开发平台:VS2008
Matlab:Matlab 2013a(64位)和Matlab 2012b(32位)
OpenCV:2.4.3
第一部分:Matlab调用C++程序
关于Matlab调用C++程序,这部分比较简单,网上参考资料也很多,就不详细叙述了,想要学习的话,搜索一下,应该很快就能实现。
第二部分:Matlab调用OpenCV
其实准确的说,也不是Matlab调用OpenCV吧,而是Matlab调用调用了OpenCV的C++程序,不过就姑且简称为Matlab调用OpenCV吧。因为通过第一部分,Matlab已经可以调用C++程序了。
关于这部分,首先说明一点的是,一定要注意版本问题。
下面开始正题。
1. 打开Matlab 2013a,在命令行输入 mex -v,出现如下内容:
-> Default options filename found in C:\Users\Suo\AppData\Roaming\MathWorks\MATLAB\R2013a
----------------------------------------------------------------
-> Options file = C:\Users\Suo\AppData\Roaming\MathWorks\MATLAB\R2013a\mexopts.bat
MATLAB = D:\MATLAB\R2013a
-> COMPILER = cl
-> Compiler flags:
COMPFLAGS = /c /GR /W3 /EHs /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0 /DMATLAB_MEX_FILE /nologo /MD
OPTIMFLAGS = /O2 /Oy- /DNDEBUG
DEBUGFLAGS = /Z7
arguments =
Name switch = /Fo
-> Pre-linking commands =
-> LINKER = link
-> Link directives:
LINKFLAGS = /dll /export:mexFunction /LIBPATH:"D:\MATLAB\R2013a\extern\lib\win64\microsoft" opencv_features2d243d.lib opencv_highgui243d.lib opencv_core243d.lib opencv_imgproc243d.lib libmx.lib libmex.lib libmat.lib /MACHINE:X64 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /incremental:NO /implib:"C:\Users\Suo\AppData\Local\Temp\mex_HhpRsb\templib.x" /MAP:".mexw64.map"
LINKDEBUGFLAGS = /DEBUG /PDB:".mexw64.pdb"
LINKFLAGSPOST =
Name directive = /out:".mexw64"
File link directive =
Lib. link directive =
Rsp file indicator = @
-> Resource Compiler = rc /fo "mexversion.res"
-> Resource Linker =
----------------------------------------------------------------
Usage:
MEX [option1 ... optionN] sourcefile1 [... sourcefileN]
[objectfile1 ... objectfileN] [libraryfile1 ... libraryfileN]
Use the -help option for more information, or consult the MATLAB API Guide.
D:\MATLAB\R2013A\BIN\MEX.PL: Error: No file names given.
Error using mex (line 206)
Unable to complete successfully.
最下面一行的红色内容不用管,打开最上面Options file 对应的那项(已红色标记),直接选中文件名,右键选择Open Selection。
2. 打开之后,进入编辑状态,找到PATH、INCLUDE、LIB和LINKFLAGS(已绿色标记)等地方,其实和VS2008中C++目录下的路径,包含文件和库文件类似。
具体如下所示:
@echo off
rem MSVC90OPTS.BAT
rem
rem Compile and link options used for building MEX-files
rem using the Microsoft Visual C++ compiler version 9.0 SP1
rem
rem $Revision: 1.1.6.11 $ $Date: 2012/07/23 18:50:44 $
rem Copyright 2007-2009 The MathWorks, Inc.
rem
rem StorageVersion: 1.0
rem C++keyFileName: MSVC90OPTS.BAT
rem C++keyName: Microsoft Visual C++ 2008
rem C++keyManufacturer: Microsoft
rem C++keyVersion: 9.0
rem C++keyLanguage: C++
rem C++keyLinkerName: Microsoft Visual C++ 2008
rem C++keyLinkerVersion: 9.0
rem
rem ********************************************************************
rem General parameters
rem ********************************************************************
set MATLAB=%MATLAB%
set VSINSTALLDIR=D:\Program Files (x86)\Microsoft Visual Studio 9.0
set VCINSTALLDIR=%VSINSTALLDIR%\VC
set OPENCVDIR=D:\OpenCV (备注:此处是设置OPENCVDIR的内容,下面要用到)
rem In this case, LINKERDIR is being used to specify the location of the SDK
set LINKERDIR=C:\Program Files\Microsoft SDKs\Windows\v6.0A\
set PATH=%VCINSTALLDIR%\bin\amd64;%LINKERDIR%\bin\x64;%VCINSTALLDIR%\BIN;%VSINSTALLDIR%\Common7\Tools;%VSINSTALLDIR%\Common7\Tools\bin;%MATLAB_BIN%;%OPENCVDIR%;%PATH%
set INCLUDE=%LINKERDIR%\include;%VCINSTALLDIR%\ATLMFC\INCLUDE;%VCINSTALLDIR%\INCLUDE;%VCINSTALLDIR%\VCPackages;%OPENCVDIR%\build\include;%OPENCVDIR%\build\include\opencv;%OPENCVDIR%\build\include\opencv2;%INCLUDE%
set LIB=%LINKERDIR%\LIB\x64;%VCINSTALLDIR%\LIB\amd64;%VCINSTALLDIR%\ATLMFC\LIB\amd64;%MATLAB%\extern\lib\win64;%OPENCVDIR%\build\x64\vc9\lib%LIB%
set MW_TARGET_ARCH=win64
rem ********************************************************************
rem Compiler parameters
rem ********************************************************************
set COMPILER=cl
set COMPFLAGS=/c /GR /W3 /EHs /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0 /DMATLAB_MEX_FILE /nologo /MD
set OPTIMFLAGS=/O2 /Oy- /DNDEBUG
set DEBUGFLAGS=/Z7
set NAME_OBJECT=/Fo
rem ********************************************************************
rem Linker parameters
rem ********************************************************************
set LIBLOC=%MATLAB%\extern\lib\win64\microsoft
set LINKER=link
set LINKFLAGS=/dll /export:%ENTRYPOINT% /LIBPATH:"%LIBLOC%" opencv_features2d243d.lib opencv_highgui243d.lib opencv_core243d.lib opencv_imgproc243d.lib libmx.lib libmex.lib libmat.lib /MACHINE:X64 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /incremental:NO /implib:"%LIB_NAME%.x" /MAP:"%OUTDIR%%MEX_NAME%%MEX_EXT%.map"
set LINKOPTIMFLAGS=
set LINKDEBUGFLAGS=/DEBUG /PDB:"%OUTDIR%%MEX_NAME%%MEX_EXT%.pdb"
set LINK_FILE=
set LINK_LIB=
set NAME_OUTPUT=/out:"%OUTDIR%%MEX_NAME%%MEX_EXT%"
set RSP_FILE_INDICATOR=@
rem ********************************************************************
rem Resource compiler parameters
rem ********************************************************************
set RC_COMPILER=rc /fo "%OUTDIR%mexversion.res"
set RC_LINKER=
set POSTLINK_CMDS=del "%LIB_NAME%.x" "%LIB_NAME%.exp"
set POSTLINK_CMDS1=mt -outputresource:"%OUTDIR%%MEX_NAME%%MEX_EXT%;2" -manifest "%OUTDIR%%MEX_NAME%%MEX_EXT%.manifest"
set POSTLINK_CMDS2=del "%OUTDIR%%MEX_NAME%%MEX_EXT%.manifest"
set POSTLINK_CMDS3=del "%OUTDIR%%MEX_NAME%%MEX_EXT%.map"
上面红色部分是修改添加的内容,切记路径中不要有空格!!!
注意include lib处要加分号,LINKFLAGS处各个lib之前要有空格!!!
切记如果32位的Matlab,一定要选择32的OpenCV库,即OpenCV库路径一定要是%OPENCVDIR%\build\x86\vc9\lib%LIB%!!!
3. 在Matlab当前目录下建立cpp文件(可以新建文本文档,然后改后缀为.cpp),程序命名为useOpenCV.cpp保存。
#include"mex.h"
#include "cv.h"
#include "highgui.h"
using namespacecv;
voidmexFunction (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;
}
4. 在matlab里面输入mex useOpenCV.cpp 编译。
5. 在matlab里输入命令调用编译好的文件:useOpenCV(‘lena.bmp’);即可调用。
注意:如果出现可以成功 mex出来mex文件,但是调用的时候提示:Invalid MEX-file '****.mexw32':
****.mexw32 不是有效的 Win32 应用程序。
或者
Invalid MEX-file '****.mexw64':
****.mexw64不是有效的 Win32 应用程序。
不要着急,这是版本问题,我是通过修改系统的环境变量中,OpenCV的路径解决的,主要原因就是在64位的Matlab中要用64位的OpenCV路径,在32位的Matlab中要用32位的OpenCV路径。
以上就是个人经过两天的调试摸索总结出来的经验,特与大家分享,希望可以共同学习,进步!
参考资料:
http://blog.csdn.net/zouxy09/article/details/20553007
http://blog.csdn.net/sxjk1987/article/details/8783016
http://blog.csdn.net/climbingc/article/details/6762424