方便的编程技巧:MEX编程笔记(一)

C++编程相比于matlab具有更高的效率,更适用于工程上的应用。matlab比较适合做数据分析,调试方便,语言简洁。为了更好的利用这两种工具,MEX混合编程是不可或缺的一项技能。本篇博客主要是记录我自己的一个小小的混合编程实践项目。

 

  1. 环境配置(MATLAB+Visual studio)

首先matlab需要安装C++的编译器,可以选择windows 自带的,如果你装了visualstudio的话(安装的时候,记得选择C++选项以及C++相关的包),建议直接选用visual studio的。使用mex -setup 命令来为matlab建立相关的环境。相关的博文可以参考https://blog.csdn.net/zaishuiyifangxym/article/details/81669673

                       

由于工作需要,我在C++程序中可能需要用到opencv等视觉相关的库,所以在安装了visual studio之后,还需要配置一下opencv的环境。这里可以参见我的另外一篇博文:https://mp.csdn.net/postedit/84975188。同时还需要把matlab自带的MEX文件库包含到路径中去:

         包含目录:     C:\Program Files\MATLAB\R2017b\extern\include
                                C:\Program Files\MATLAB\R2017b\extern\include\win64

         库目录 :       C:\Program Files\MATLAB\R2017b\extern\lib\win64\microsoft

         但是,这并不算完,我们需要在创建的工程中,建立一个混编的C++文件

 

 

     2. MEX编程起步

配置好环境之后,就可以来着手编程了,其实要掌握这项技能很简单,把握好以下两点:

  •    MEX编程语法
  •    编译方法

 a. MEX中用过mexFunction 代替了C++中的main函数

#include "mex.h"
#include <opencv/cv.h>
#include <opencv/cxcore.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include "stdio.h"
#include <iostream>
//nlhs是输出的参数个数,plhs为左边指数指针,nrhs为右边输入参数的个数,prhs为输入参数的指针
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{

}

四个参数分别用来输出和输入数据: nlhs 输出参数个数,plhs 输出参数指针 (nrhs和prhs是输入参数相关的)。

注意: 我们对输出和输入参数的操作都是通过指针的方式进行的。而且默认的传递的数据都是double类型的矩阵,矩阵不同于C语言中的按行存储,这里传入的矩阵是按列来存储的,所以访问格式上会与我们常用的方式有所区别:

	uchar *pData = (uchar *)mxGetPr(prhs[1]);//prhs[1]是第二个输入参数,同时强转为uchar

	// 复制数据
	cv::Mat im(rows, cols, CV_8U);
	for (int i = 0; i < rows; i++)
	{
		for (int j = 0; j < cols; j++)
		{
			im.at<uchar>(i, j) = pData[rows*j + i];//按列访问数据
		}
	}

常用的一些函数:

short rows = mxGetM(prhs[1]);//矩阵的行
short cols = mxGetN(prhs[1]);//矩阵的宽度
double *label= (double *)mxGetPr(prhs[0]);//获取数据的指针


//定义输出的变量
mwSize dim[2] = { im.cols,im.rows };//定义输出的尺寸变量
plhs[0] = mxCreateNumericArray(2, dim, mxUINT8_CLASS, mxREAL);//创建
memcpy(mxGetPr(plhs[0]), im.data, sizeof(uchar)*im.cols*im.rows);//拷贝数据

 

b.编译

如果没有使用第三方库的话,直接在matlab里面使用mex  **.cpp就可以进行编译了,但是比如我使用了opencv,那么就需要自己写一个编译文件,包含所需要用的库和头文件:

cd D:\专业学习\程序代码\mex\test\src
OpenCV_INLCUDE_DIR = '-ID:\opencv\opencv\build\include -ID:\opencv\opencv\build\include\opencv -ID:\opencv\opencv\build\include\opencv2 ';
OpenCV_LIBRARY_DIR = '-LD:\opencv\opencv\build\x64\vc12\lib -lopencv_core2413 -lopencv_imgproc2413 -lopencv_highgui2413 -lopencv_contrib2413 -lopencv_legacy2413';  
%对于库的包含,不懂的可以看一看doc mex,里面有写
eval(['mex matlabcvline.cpp ' OpenCV_INLCUDE_DIR OpenCV_LIBRARY_DIR]);  

最后附上一个例程,以供自己复习

1.mex文件:

#include "mex.h"
#include "stdio.h"
#include <opencv/cv.h>
#include <opencv/cxcore.hpp>
#include <opencv2\features2d\features2d.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
	//实现a+b
	//plhs输出参数,prhs输入参数
	//double *a = mxGetPr(prhs[0]);
	//double *b = mxGetPr(prhs[1]);
	//plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
	//double *c = mxGetPr(plhs[0]);
	//*c = *a + *b;
	printf("hello my first mex.cpp\n");
	cv::VideoCapture cam(0);
	cv::Mat im;
	cam >> im;
	cv::imshow("im", im);
	cv::waitKey(1);
	//cam.release();
}

2. 编译文件

cd D:\专业学习\程序代码\mex\test\src
OpenCV_INLCUDE_DIR = '-ID:\opencv\opencv\build\include -ID:\opencv\opencv\build\include\opencv -ID:\opencv\opencv\build\include\opencv2 ';
OpenCV_LIBRARY_DIR = '-LD:\opencv\opencv\build\x64\vc12\lib -lopencv_core2413 -lopencv_imgproc2413 -lopencv_highgui2413 -lopencv_contrib2413 -lopencv_legacy2413';  
%对于库的包含,不懂的可以看一看doc mex,里面有写
eval(['mex test.cpp ' OpenCV_INLCUDE_DIR OpenCV_LIBRARY_DIR]);  

3. matlab调用文件

clc;
clearvars;
close all;
addpath('D:\专业学习\程序代码\mex\test\src\');%mex文件
while 1 
test;
end

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

syvge

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值