matalb具有灵活的图像处理,代码编写起来简洁而高效。而OpenCV具有很多成熟的计算机视觉算法,能够处理很多实时的识别处理等问题,而且代码运行起来效率很高。所以如何结合两者之间的优点,是让很多学术人员、及工程开发者趋之若鹜的事情。本例子,就是为了测试将opencv处理的结果存储入matlab能够处理的.mat文件,方便matalb能后期对数据进行更为灵活的操作而进行的。例子比较简单,但是本人也花费了大量时间测试成功。
测试程序下载地址为:Visual Studio 中同时使用OpenCV和matlab mat文件操作 2016-1-24(早上) (需要你进入下载目录后自己找到这个文件夹)
另外一种将openCV和matlab结合起来的方式是使用cmex方式,用的是mexFunction, 然后用matlab编译器mex name.cpp方式编译然后以函数形式调用。这方面的内容请参考本人博客中的另外三篇文章matlab调用opencv函数的配置,[转] Matlab与C++混合编程,添加OpenCV库,[转] Matlab与C++混合编程(依赖OpenCV)。
。
1. 平台
Visual Studio 2012,
Matlab2015a,
OpenCV 2.4.10
2. 项目配置
(1)如下图所示,配置为活动X64, 也就是64位下的debug模式,这样就可以出问题时能调试。
(2)包含目录、库目录配置
包含目录
E:\Program Files\MATLAB\R2015a\extern\include
E:\Program Files\MATLAB\R2015a\extern\include\win64
D:\Program Files\opencv\build\include
D:\Program Files\opencv\build\include\opencv
D:\Program Files\opencv\build\include\opencv2
库目录
E:\Program Files\MATLAB\R2015a\extern\lib\win64\microsoft
D:\Program Files\opencv\build\x64\vc11\lib
备注,请事先配置好64位openCV的环境变量,如将D:\Program Files\opencv\build\x64\vc11\bin加入系统环境变量。否则编译通过,但是运行时提示出错。
(3) 链接器--输入中的设置
libmx.lib
libmat.lib
libmex.lib
opencv_calib3d2410d.lib
opencv_contrib2410d.lib
opencv_core2410d.lib
opencv_features2d2410d.lib
opencv_flann2410d.lib
opencv_gpu2410d.lib
opencv_highgui2410d.lib
opencv_imgproc2410d.lib
opencv_legacy2410d.lib
opencv_ml2410d.lib
opencv_objdetect2410d.lib
opencv_ts2410d.lib
opencv_video2410d.lib
3. 代码的编写
#include <stdio.h> #include <stdlib.h> #include <memory.h> #include <math.h> #include "highgui.h" #include "cv.h" #include "drawai.h" // mex #include "mat.h" #include <string.h> /* For strcmp() */ #include <stdlib.h> /* For EXIT_FAILURE, EXIT_SUCCESS */ #define BUFSIZE 256 typedef unsigned char byte; using namespace std; using namespace cv; Mat ChangeImg(Mat &img, const uchar* table); Mat& ScanImageAndReduceIterator(Mat& I, const uchar* const table); void main() { // Example 2 // 内存方面的测试 //int * mem_int; //int b; //mem_int=(int*)calloc(10*10,sizeof(*mem_int)); //memset(mem_int,0,10*10*sizeof(int)); //printf("%d %d\nHellow c test\nWelcome back!\n",mem_int[0],mem_int[10]); //scanf("%d",&b); //printf("you inputed the number %d\n",b); ///*Sample2 OpenCV进行灰度操作与绘图*/ //const char *picName="Jellyfish.jpg"; //Mat img=imread(picName,CV_LOAD_IMAGE_GRAYSCALE); //uchar table[256];//映射表,规定了变换前后灰度值的对应关 //for (int i=0;i<256;i++) // table[i]=i/100*100;//这里利用了C++的语言特性i/100只会留下整数部分 //imshow("变换前",img); //Mat img_th=ChangeImg(img,table); //namedWindow("变换后", CV_WINDOW_AUTOSIZE); //imshow("变换后",img_th); //// Example 2 ///* Draw lines */ ////圆心 //Point center = Point(255,255); ////半径 //int r = 100; ////承载图像 //Mat draw_board(500,500,CV_8UC3,Scalar(255,255,255)); ////参数为:承载的图像、圆心、半径、颜色、粗细、线型 //circle(draw_board,center,r,Scalar(0,0,0)); //line(draw_board,Point(100,50),Point(200,100),Scalar(100,0,255),2,8,0); //line(draw_board,Point(100,70),Point(200,120),Scalar(100,0,255),10,8,0); //line(draw_board,Point(100,90),Point(200,140),Scalar(100,0,255),5,8,0); //line(draw_board,Point(100,90),Point(200,140),Scalar(100,0,0),1,8,0); //rectangle(draw_board,Point(300,200),Point(400,260),Scalar(100,80,0)); ///* Draw picture */ //string words="Merry chrismas, good luck!"; //putText(draw_board,words,Point(100,400),CV_FONT_HERSHEY_COMPLEX,0.5,Scalar(100,200,0)); // //imshow("底板",draw_board); //cvMoveWindow("底板",300,500); //cvWaitKey(0); // Example 3 /* byte dst; float src; dst=10; src=1.56; dst=(byte)src; char str[50]; sprintf(str,"This is sprintf test %d",dst); printf("The result is: %d\n",dst); printf("\n Out is %s\n",str);*/ // Example 4 drawai::drawExample1(); // Example 5 /*printf("\n\nDouble Size %d, \nDouble Pointer size %d,\nDouble Pointer Pointer size %d\n", sizeof(double),sizeof(double*),sizeof(double**)); printf("\n\nunsigned long Size %d, \nunsigned int size %d\n", sizeof(unsigned long),sizeof(unsigned int)); int b=0,a=0; b=a=5; printf("\nb=a=5, result is b=%d. a=%d\n",b,a);*/ // Example 6 MATFile *pmat; mxArray *pa1, *pa2, *pa3; double data[9] = { 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 }; const char *file = "mattest.mat"; char str[BUFSIZE]; int status; printf("Creating file %s...\n\n", file); pmat = matOpen(file, "w"); if (pmat == NULL) { printf("Error creating file %s\n", file); printf("(Do you have write permission in this directory?)\n"); return; } /* pa1 */ pa1 = mxCreateDoubleMatrix(3,3,mxREAL); if (pa1 == NULL) { printf("%s : Out of memory on line %d\n", __FILE__, __LINE__); printf("Unable to create mxArray.\n"); return; } status = matPutVariable(pmat, "LocalDouble", pa1); if (status != 0) { printf("%s : Error using matPutVariable on line %d\n", __FILE__, __LINE__); return; } /* pa2 */ pa2 = mxCreateDoubleMatrix(3,3,mxREAL); if (pa2 == NULL) { printf("%s : Out of memory on line %d\n", __FILE__, __LINE__); printf("Unable to create mxArray.\n"); return; } memcpy((void *)(mxGetPr(pa2)), (void *)data, sizeof(data)); status = matPutVariableAsGlobal(pmat, "GlobalDouble", pa2); if (status != 0) { printf("Error using matPutVariableAsGlobal\n"); return; } /* pa3 */ pa3 = mxCreateString("MATLAB: the language of technical computing"); if (pa3 == NULL) { printf("%s : Out of memory on line %d\n", __FILE__, __LINE__); printf("Unable to create string mxArray.\n"); return; } status = matPutVariable(pmat, "LocalString", pa3); if (status != 0) { printf("%s : Error using matPutVariable on line %d\n", __FILE__, __LINE__); return; } /* * Ooops! we need to copy data before writing the array. (Well, * ok, this was really intentional.) This demonstrates that * matPutVariable will overwrite an existing array in a MAT-file. */ memcpy((void *)(mxGetPr(pa1)), (void *)data, sizeof(data)); status = matPutVariable(pmat, "LocalDouble", pa1); if (status != 0) { printf("%s : Error using matPutVariable on line %d\n", __FILE__, __LINE__); return; } /* clean up */ mxDestroyArray(pa1); mxDestroyArray(pa2); mxDestroyArray(pa3); if (matClose(pmat) != 0) { printf("Error closing file %s\n",file); return; } /* * Re-open file and verify its contents with matGetVariable */ pmat = matOpen(file, "r"); if (pmat == NULL) { printf("Error reopening file %s\n", file); return; } /* * Read in each array we just wrote */ pa1 = matGetVariable(pmat, "LocalDouble"); if (pa1 == NULL) { printf("Error reading existing matrix LocalDouble\n"); return; } if (mxGetNumberOfDimensions(pa1) != 2) { printf("Error saving matrix: result does not have two dimensions\n"); return; } pa2 = matGetVariable(pmat, "GlobalDouble"); if (pa2 == NULL) { printf("Error reading existing matrix GlobalDouble\n"); return; } if (!(mxIsFromGlobalWS(pa2))) { printf("Error saving global matrix: result is not global\n"); return; } pa3 = matGetVariable(pmat, "LocalString"); if (pa3 == NULL) { printf("Error reading existing matrix LocalString\n"); return; } status = mxGetString(pa3, str, sizeof(str)); if(status != 0) { printf("Not enough space. String is truncated."); return; } if (strcmp(str, "MATLAB: the language of technical computing")) { printf("Error saving string: result has incorrect contents\n"); return; } /* clean up before exit */ mxDestroyArray(pa1); mxDestroyArray(pa2); mxDestroyArray(pa3); if (matClose(pmat) != 0) { printf("Error closing file %s\n",file); return; } printf("Done\n"); return; }
这是以一个绘图的程序OpenCV、在控制台应用程序下生成.mat文件(可以作为matlab后续处理的数据输入)为例进行的测试。
运行的结果,会在项目根目录下生成下面的mattest.mat文件