VS2010和Matlab混合编程 ---调试Mex文件
原文链接 http://wangcaiyong.com/2015/07/14/vs-mex/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
首先说明我的软件配置: Computer: Windows7 SP1 64位 VS2010:旗舰版 SP1 Matlab:R2012a ,64位 下面我们将具体讲述调试Mex文件的全过程。(有图有真相哟! ) <!--more-->
注意1:我们下面的做法是在64位基础上进行的,对于32位同适用,只要你注意减少某些操作即可。我们会在合适的地方进行相应的说明的,所以请放心操作。 注意2:由于这里建立的Mex文件里包含了opencv 2.4.9,所以如下的配置也会涉及到opencv的部分设置,如include,lib路径和附加依赖项,但是如果你也想使用opencv的话,你还需设置环境变量,在Path中添加bin路径。
MEX的说明
写MEX程序其实就是写一个DLL程序,所以你可以使用C,C++,Fortran等多种编程语言来写。
编写MEX程序的编辑器可以使用MATLAB的代码编辑器,也可使用自己的C++编辑器,如VS2008等。
用MATLAB的编辑器的好处是,MEX函数会加粗高亮显示,这给程序编写带来便利,可惜无法动态调试。如用VC,即可编译也可调试,比较方便。mex的编译结果实际上就是一个带输出函数mexFunction 的dll文件,所以会用VC编写和调试dll,就会用VC编写和调试MEX程序。
新建一个win32 dll空项目
打开vs2010, 文件,新建项目,选择Visual C++,点击Win32,选择Win32控制台应用程序,填写程序名字和相应位置,如我这里填:MexTest,点击下一步,直到出现如下图:
按照图示操作,点击完成,则新建了一个空的win32 dll项目.
配置环境
32位平台上操作步骤:
点击 【项目】,选择【属性】,在【配置属性】选择【VC++目录】, 在【包含目录】,加入matlab下安装目录下\extern\include和opencv的include路径: C:\opencv\build\include C:\opencv\build\include\opencv C:\opencv\build\include\opencv2 这三个目录。(注意:修改你自己的opencv路径) 【库目录】加入\extern\lib\win32\microsoft和opencv的lib路径: C:\opencv\build\x86\vc10\lib 【链接器】->【输入】->【附加依赖项】输入:
libmx.lib
libeng.lib
libmat.lib
libmex.lib
opencv_ml249d.lib
opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_objdetect249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_nonfree249d.lib
opencv_ocl249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_superres249d.lib
opencv_videostab249d.lib
最后【链接器】->【常规】->【输出文件】里改成
$(OutDir)$(TargetName).mexw32
64位平台上操作步骤:
点击 【项目】,选择【属性】,【链接器】->【高级】->【目标计算机】设置成MachineX64 (/MACHINE:X64),然后在【生成】->【配置管理器】->【活动解决方案平台(P):】,点击,选择【新建】,然后在打开的对话框中, 按照如下操作: 点击确定。 然后继续打开项目属性,这时发现平台已改成64位,这时我们同样按照如上32平台的方法设置相应的环境。具体如下:
- 【链接器】->【常规】->【输出文件】里改成
$(OutDir)$(TargetName).mexw64
- 输入include,lib路径,添加附加依赖项,如下图: ### 添加源文件 在源文件中新建mex文件,(这里的文名必须与工程名相同) 如我的MexTest.cpp文件如下:
// Interface: convert an image to gray and return to Matlab
// Author : zouxy
// Date : 2014-03-05
// HomePage : http://blog.csdn.net/zouxy09
// Email : zouxy09@qq.com
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "mex.h"
#include <string>
#include <iostream>
using namespace std;
using namespace cv;
/*******************************************************
Usage: [imageMatrix] = RGB2Gray('imageFile.jpeg');
Input:
a image file
OutPut:
a matrix of image which can be read by Matlab
**********************************************************/
void exit_with_help()
{
mexPrintf(
"Usage: [imageMatrix] = DenseTrack('imageFile.jpg');\n"
);
}
static void fake_answer(mxArray *plhs[])
{
plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
}
void RGB2Gray(char *filename, mxArray *plhs[])
{
// read the image
Mat image = imread(filename);
if(image.empty()) {
mexPrintf("can't open input file %s\n", filename);
fake_answer(plhs);
return;
}
// convert it to gray format
Mat gray;
if (image.channels() == 3)
cvtColor(image, gray, CV_RGB2GRAY);
else
image.copyTo(gray);
// convert the result to Matlab-supported format for returning
int rows = gray.rows;
int cols = gray.cols;
plhs[0] = mxCreateDoubleMatrix(rows, cols, mxREAL);
double *imgMat;
imgMat = mxGetPr(plhs[0]);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
*(imgMat + i + j * rows) = (double)gray.at<uchar>(i, j);
return;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if(nrhs == 1)
{
char filename[256];
mxGetString(prhs[0], filename, mxGetN(prhs[0]) + 1);
if(filename == NULL)
{
mexPrintf("Error: filename is NULL\n");
exit_with_help();
return;
}
RGB2Gray(filename, plhs);
}
else
{
exit_with_help();
fake_answer(plhs);
return;
}
}
添加def文件 代码:
LIBRARY
EXPORTS mexFunction
按F7或者选择【生成】->【生成解决方案】,生成成功,我们就可以在
E:\opencv\c++\MexTest\x64\Debug
找到所需要的MexTest.mexw64了。
MATLAB设置
(1) mex 命令设置
运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入
mex -setup
命令后,按回车键,安装 Matlab 编译器;
(2) mbuild 命令设置
运行 Matlab ,在 Matlab 的命令窗口 (Command Window) 键入
mbuild -setup
命令后,按回车键,安装 Matlab 编译器;
(3) 在 Matlab 的命令窗口 (Command Window) 键入
cd(prefdir);
savepath prefdir;
启动 MATLAB add-in 工具条.
调试
将matlab的current folder 设置成mexw64文件所在的路径,
在vs2010的源代码MexTest.cpp设置断点,然后
vs2010-【工具】-【附加到线程】-选择MATLAB.exe,点击附加。
matlab下输入代码或者函数(即mexw64文件的文件名),即会跳转到vs的断点处。如这里我输入:
img = MexTest('E:\opencv\c++\1.jpg');
就会马上跳转到vs2010的源代码中,你可以使用F10进行调试了。
参考文献:
- http://blog.sina.com.cn/s/blog_a7e72e940101cti9.html
- http://www.cnblogs.com/avril/archive/2012/09/12/2681192.html
- http://www.cnblogs.com/lukylu/p/4042306.html
- http://www.cnblogs.com/avril/archive/2012/09/12/2681192.html
- http://www.blogbus.com/shijuanfeng-logs/106781870.html
- http://blog.csdn.net/zouxy09/article/details/20553007