原文地址百度账户 aleasa123
方式1
1、 首先保证vs2010能正确调用opencv函数,
2、 Matlab中选择编译器,操作如下:
打开matlab2012,输入mex –setup,出现如下提示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
Welcome to mex -setup. This utility will help you set up
a default compiler. For a list of supported compilers, see
http://www.mathworks.com/ support /compilers/R2012a/win32.html
Please choose your compiler for building MEX-files:
Would you like mex to locate installed compilers [y]/n?
输入y,出现如下提示: Select a compiler: [1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2012a\sys\lcc [2] Microsoft Visual C++ 2010 in C:\Program Files\Microsoft Visual Studio 2010 [0] None Compiler: 输入2,出现如下提示: Please verify your choices: Compiler: Microsoft Visual C++ 2010 Location: C:\Program Files\Microsoft Visual Studio 2010 Are these correct [y]/n? 输入y 出现如下提示,表明成功: *************************************************************************** Warning: MEX-files generated using Microsoft Visual C++ 2010 require
that Microsoft Visual Studio 2010 run -time libraries be
available on the computer they are run on.
If you plan to redistribute your MEX-files to other MATLAB
users, be sure that they have the run -time libraries.
*************************************************************************** Trying to update options file: C:\Documents and Settings\zhangjing\Application Data\MathWorks\MATLAB\R2012a\mexopts.bat
From template: C:\PROGRA~1\MATLAB\R2012a\bin\win32\mexopts\msvc100opts.bat Done . . . ************************************************************************** Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. In the near future
you will be required to update your code to utilize the new
API. You can find more information about this at:
http://www.mathworks.com/ help /techdoc/matlab_external/bsflnue-1.html
Building with the -largeArrayDims option enables the new API.
************************************************************************** |
3、 配置一些目录
在matlab中,输入mex –v
下面会有显示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
-> Default options filename found in C:\Documents and Settings\zhangjing\Application Data\MathWorks\MATLAB\R2012a
---------------------------- -> Options file = C:\Documents and Settings\zhangjing\Application Data\MathWorks\MATLAB\R2012a\mexopts.bat
MATLAB = C:\PROGRA~1\MATLAB\R2012A
-> 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
。。。。。。。。。(此处省略一些) 选中上面Options file=后面的部分,右键->Open Selection,打开mexopts.bat 找到下面部分,增加红色的部分 set MATLAB= %MATLAB%
set VSINSTALLDIR=C:\Program Files\Microsoft Visual Studio 2010
set VCINSTALLDIR= %VSINSTALLDIR%\VC
rem In this case , LINKERDIR is being used to specify the location of the SDK
set LINKERDIR=C:\Program Files\Microsoft SDKs\Windows\v7.0A\
set PATH= %VCINSTALLDIR%\bin;%VCINSTALLDIR%\VCPackages;%VSINSTALLDIR%\Common7\IDE;%VSINSTALLDIR%\Common7\Tools;%LINKERDIR%\bin;%MATLAB_BIN%;%PATH%
set INCLUDE= %VCINSTALLDIR%\INCLUDE;%VCINSTALLDIR%\ATLMFC\INCLUDE;%LINKERDIR%\include;%INCLUDE%;D:\opencv\include;D:\opencv\include\opencv;D:\opencv\include\opencv2
set LIB= %VCINSTALLDIR%\LIB;%VCINSTALLDIR%\ATLMFC\LIB;%LINKERDIR%\lib;%MATLAB%\extern\lib\win32;%LIB%;D:\opencv\build\x86\vc10\lib
set MW_TARGET_ARCH=win32
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\win32\microsoft
set LINKER=link
set LINKFLAGS=/dll /export: %ENTRYPOINT% /LIBPATH:"%LIBLOC%" opencv_core231d.lib opencv_highgui231d.lib opencv_video231d.lib opencv_ml231d.lib opencv_legacy231d.lib opencv_imgproc231d.lib opencv_flann231d.lib opencv_features2d231d.lib opencv_calib3d231d.lib opencv_objdetect231d.lib opencv_contrib231d.lib libmx.lib libmex.lib libmat.lib /MACHINE:X86 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 /manifest /incremental:NO /implib:"%LIB_NAME%.x" /MAP:"%OUTDIR%%MEX_NAME%%MEX_EXT%.map"
set LINKOPTIMFLAGS=
(注意上面include lib处要加分号,LINKFLAGS处各个lib之前要回空格) |
在matlab当前目录下建立cpp文件(简单方法,txt改后缀为cpp),vs打开敲入代码,代码需要是Matlab的C语言接口风格,函数内部调用OpenCV函数演示功能,简化后的代码:程序命名为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; }
5 在matlab里输入 mex useOpenCV.cpp编译。
6 在matlab里输入命令调用编译好的文件:useOpenCV(‘lena.bmp’);即可调用。
方式2
利用Opencv2.4.3中的头文件和库文件
在matlab中利用mex命令编译C/C++文件时,可以利用Opencv2.4.3的头文件和库文件中已经定义的函数和类等模块。
(1) 对于头文件中已经定义的函数和类等模块时,需要在Opencv2.4.3的安装目录下找到对
应的头文件(*.h或*.hpp),并将其拷贝至mex命令所要编译的文件相同的目录下,并在C/C++文件中“#include”这个头文件,并将这个头文件中所涉及到的
“F:\opencv\build\include\opencv2”目录下的所有文件也拷贝至mex命令所要编译的文件相同的目录下。“ F:\opencv”为Opencv2.4.3的安装目录。
(2) 对于库文件中已经定义的函数和类等模块时,在C/C++文件中包含这个库文件,语句为
#pragma comment(lib, "opencv_calib3d243d.lib")
#pragma comment(lib, "opencv_contrib243d.lib")
#pragma comment(lib, "opencv_core243d.lib")
#pragma comment(lib, "opencv_features2d243d.lib")
#pragma comment(lib, "opencv_flann243d.lib")
#pragma comment(lib, "opencv_gpu243d.lib")
#pragma comment(lib, "opencv_highgui243d.lib")
#pragma comment(lib, "opencv_imgproc243d.lib")
#pragma comment(lib, "opencv_legacy243d.lib")
#pragma comment(lib, "opencv_ml243d.lib")
#pragma comment(lib, "opencv_objdetect243d.lib")
#pragma comment(lib, "opencv_ts243d.lib")
#pragma comment(lib, "opencv_video243d.lib")
并将上述所有的库文件从opencv的安装目录下找到拷贝至mex命令所要编译的文件相同的目
录下。
(3) 利用mex命令编译“*.cpp”文件就可获得“*.mexw64”文件。
(4) 例子
#include "mex.h" #include "cv.h" //#include "highgui.h" #include "highgui.h" #pragma comment(lib, "opencv_calib3d243d.lib") #pragma comment(lib, "opencv_contrib243d.lib") #pragma comment(lib, "opencv_core243d.lib") #pragma comment(lib, "opencv_features2d243d.lib") #pragma comment(lib, "opencv_flann243d.lib") #pragma comment(lib, "opencv_gpu243d.lib") #pragma comment(lib, "opencv_highgui243d.lib") #pragma comment(lib, "opencv_imgproc243d.lib") #pragma comment(lib, "opencv_legacy243d.lib") #pragma comment(lib, "opencv_ml243d.lib") #pragma comment(lib, "opencv_objdetect243d.lib") #pragma comment(lib, "opencv_ts243d.lib") #pragma comment(lib, "opencv_video243d.lib") IplImage *grey1 = 0, *grey0 = 0, *pyramid1 = 0, *pyramid0 = 0; int win_size = 5; CvPoint2D32f* points[2] = {0,0}; void loadImageFromMatlab(const mxArray *mxImage, IplImage *image) { unsigned char *values = (unsigned char *) mxGetPr(mxImage); int widthStep = image‐>widthStep; int N = mxGetN(mxImage); // width int M = mxGetM(mxImage); // height for(int i=0;i<N;i++) for(int j=0;j<M;j++) image‐>imageData[j*widthStep+i] = values[j+i*M]; } void mexFunction(int plhs_size, mxArray *plhs[], int prhs_size, const mxArray *prhs[]) { // Load images if (prhs_size ==4) { win_size = *mxGetPr(prhs[3]); } int N = mxGetN(prhs[0]); int M = mxGetM(prhs[0]); grey0 = cvCreateImage( cvSize(N, M), 8, 1 ); grey1 = cvCreateImage( cvSize(N, M), 8, 1 ); loadImageFromMatlab(prhs[0],grey0); loadImageFromMatlab(prhs[1],grey1);
// Load feature points double *fp = mxGetPr(prhs[2]); int num_pts = mxGetN(prhs[2]); points[0] = (CvPoint2D32f*)cvAlloc(num_pts*sizeof(points[0][0])); points[1] = (CvPoint2D32f*)cvAlloc(num_pts*sizeof(points[0][0])); char *status = (char*)cvAlloc(num_pts); float *error = (float*) cvAlloc(num_pts*sizeof(float)); for (int i = 0; i < num_pts; i++) { points[0][i].x = fp[2*i];
points[0][i].y = fp[2*i+1]; } // neni treba, urychleni z fpt 40 ‐> fps 200 //cvFindCornerSubPix( grey0, points[0], num_pts, cvSize(win_size,win_size), cvSize(‐1,‐1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); pyramid1 = cvCreateImage( cvGetSize(grey1), 8, 1 );
pyramid0 = cvCreateImage( cvGetSize(grey1), 8, 1 ); cvCalcOpticalFlowPyrLK( grey0, grey1, pyramid0, pyramid1, points[0], points[1], num_pts, cvSize(win_size,win_size), 6, status, error, cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), 0 ); // Output plhs[0] = mxCreateDoubleMatrix(6, num_pts, mxREAL);
double *output = mxGetPr(plhs[0]);
for (int i = 0; i < num_pts; i++)
{ output[6*i] = (double) points[0][i].x;
output[6*i+1] = (double) points[0][i].y;
output[6*i+2] = (double) points[1][i].x;
output[6*i+3] = (double) points[1][i].y;
output[6*i+4] = (double) error[i];
output[6*i+5] = (double) status[i]; //output[5*i+5] = (double) error[i];
} // Tidy up cvReleaseImage( &pyramid0 );
cvReleaseImage( &pyramid1 );
cvReleaseImage( &grey0 );
cvReleaseImage( &grey1 );
return;
}