基本思路是在内存中保留一块内存区域用于存储和相机有关的配置信息和图像,C接口程序接受Matlab传来的参数,并初始化相机,将相机配置参数存入内存的堆区域,返回值为该内存区域的首地址,转为Int类型输出,Matlab程序只需持有该地址即可。
//mvc_init_camera.cpp
#include
#include
#include
#include "MVCAPI.h"
#include "mex.h"
HANDLE* m_phMVCs;
BYTE* m_pRawDatas[5];
struct CapInfoStruct* m_pCapInfos;
int* pplhs0;
void free_data(int camera_num);
void init_camera(int camera_num, int* pcamera_ids, int* pwidths, int* pheights, int* phOffs, int* pvOffs);
/***
*输入参数:五个行向量,分别是相机标号,每个相机获取图像的宽和高,图像的水平偏置和垂直偏置
*输出参数:n*3 矩阵
* |相机标号1|m_hMVs指针|m_CapInfo指针|
* |相机标号2|m_hMVs指针|m_CapInfo指针|
* ...
***/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
int camera_num,i;
int camera_ids[6];
int widths[6];
int heights[6];
int hOffs[6];
int vOffs[6];
double *pInputs[5];
//分别相机标号、宽、高、水平偏置、垂直偏置 (都是行向量)
if(nrhs != 5) {
mexErrMsgIdAndTxt("MyToolbox:mvc_init_camera:nrhs",
"Five inputs required.");
}
//输出[相机标号,m_hMVs指针,m_CapInfo指针]
if(nlhs != 1) {
mexErrMsgIdAndTxt("MyToolbox:mvc_init_camera:nlhs",
"One output required.");
}
camera_num = mxGetN(prhs[0]);
for (i=0;i<5;++i){
pInputs[i] = mxGetPr(prhs[i]);
}
for (i=0;iint)(pInputs[0][i]);
widths[i] = (int)(pInputs[1][i]);
heights[i] = (int)(pInputs[2][i]);
hOffs[i] = (int)(pInputs[3][i]);
vOffs[i] = (int)(pInputs[4][i]);
mexPrintf("camera: %d %d %d %d %d\n",camera_ids[i],widths[i],heights[i],hOffs[i],vOffs[i]);
}
m_phMVCs = (HANDLE*)malloc(camera_num*sizeof(HANDLE));
memset(m_phMVCs,0,camera_num*sizeof(HANDLE));
m_pCapInfos = (struct CapInfoStruct*)malloc(camera_num*sizeof(struct CapInfoStruct));
memset(m_pCapInfos,0,camera_num*sizeof(struct CapInfoStruct));
init_camera(camera_num,camera_ids,widths,heights,hOffs,vOffs);
plhs[0] = mxCreateNumericMatrix(3,(mwSize)camera_num,mxINT32_CLASS,mxREAL);
pplhs0 = (int*)mxGetData(plhs[0]);
for (i=0;i3+0] = camera_ids[i];
pplhs0[i*3+1] = (int)(m_phMVCs+i);
pplhs0[i*3+2] = (int)(m_pCapInfos+i);
}
}
void init_camera(int camera_num, int* pcamera_ids, int* pwidths, int* pheights, int* phOffs, int* pvOffs){
int nIndex=0;
int rt;
int RawDataSize;
for (nIndex=0;nIndexmalloc(RawDataSize*sizeof(BYTE));
memset(m_pRawDatas[nIndex],0,RawDataSize*sizeof(BYTE));
struct CapInfoStruct *m_pCapInfo = m_pCapInfos+nIndex;
memset(m_pCapInfo, 0, sizeof(struct CapInfoStruct));
m_pCapInfo->Buffer = m_pRawDatas[nIndex];
m_pCapInfo->Height = pheights[nIndex];
m_pCapInfo->Width = pwidths[nIndex];
m_pCapInfo->HorizontalOffset = phOffs[nIndex];
m_pCapInfo->VerticalOffset = pvOffs[nIndex];
m_pCapInfo->Exposure = 1024;
m_pCapInfo->Gain[0] = 17;
m_pCapInfo->Gain[1] = 9;
m_pCapInfo->Gain[2] = 15;
m_pCapInfo->Control = 0;
memset(m_pCapInfo->Reserved, 0, 8);
m_pCapInfo->Reserved[0] = 3;
m_phMVCs[nIndex] = 0;
mexPrintf("init camera: %d %d %d\n",pcamera_ids[nIndex],m_pCapInfo,&m_phMVCs[nIndex]);
rt = MV_Usb2Init("MVC1000", pcamera_ids+nIndex, m_pCapInfo, m_phMVCs+nIndex);
if(ResSuccess != rt)
{
free_data(nIndex+1);
mexPrintf("rt:%d\n",rt);
mexErrMsgTxt("Can not open USB camera");
}
}
for (nIndex=0;nIndexvoid free_data(int camera_num){
for (int i=0;ifree(m_pRawDatas[i]);
}
free(m_phMVCs);
free(m_pCapInfos);
}
输入需要获取图像的相机Id,以及其对应的m_phMVCs指针地址即可,输出值为cell类型,每个单元中保存有一副图像。cell{image1,image2,image3,…}
//mvc_get_camera.cpp
#include
#include
#include
#include "MVCAPI.h"
#include "mex.h"
HANDLE* m_phMVCs;
struct CapInfoStruct* m_pCapInfos;
double* pprhs0;
int* pprhs1;
BYTE* pImage;
/***
*输入参数:相机Id(行向量),m_phMVCs指针地址(行向量)
*输出参数:Matlab的Cell类型,每个单元存一副图像
***/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
int camera_num,image_num,i,j,h,w,num;
int camera_ids[6];
int image_ids[6];
int im2ca[6] = {-1,-1,-1,-1,-1,-1 }; //图像序号转相机序号
mxArray *pIms[6];
mwSize dims[4];
/*
*[id id id
* hMVC hMVC hMVC
* Cap Cap Cap]
*/
//相机ids、mvcMgr
if(nrhs != 2) {
mexErrMsgIdAndTxt("MyToolbox:mvc_get_image:nrhs",
"Two inputs required.");
}
//输出图像结构体
if(nlhs != 1) {
mexErrMsgIdAndTxt("MyToolbox:mvc_get_image:nlhs",
"One output required.");
}
image_num = mxGetN(prhs[0]);
camera_num = mxGetN(prhs[1]);
pprhs0 = mxGetPr(prhs[0]);
pprhs1 = (int*)mxGetData(prhs[1]);
for (i=0;iint)(pprhs1[i*3]);
//mexPrintf("camera: %d\n",camera_ids[i]);
}
for (i=0;iint)(pprhs0[i]);
//mexPrintf("image: %d\n",image_ids[i]);
}
m_phMVCs = (HANDLE*)pprhs1[1];
m_pCapInfos = (struct CapInfoStruct*)pprhs1[2];
for (i=0;ifor (j=0;jif (image_ids[i]==camera_ids[j]){
MV_Usb2GetRawData(m_phMVCs[j],&m_pCapInfos[j]);
im2ca[i] = j;
}
}
if (im2ca[i]<0){
mexErrMsgTxt("Camera id not exist");
}
}
dims[0] = m_pCapInfos[0].Width;;
dims[1] = m_pCapInfos[0].Height;;
plhs[0] = mxCreateCellMatrix(1,image_num);
for (i=0;i0],i,pIms[i]);
}
}
需去初始化相机并释放内存空间
//mvc_uinit_camera.cpp
#include
#include
#include
#include "MVCAPI.h"
#include "mex.h"
HANDLE* m_phMVCs;
struct CapInfoStruct* m_pCapInfos;
int* pplhs0;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
int camera_num,i;
int camera_ids[6];
/*
*[id id id
* hMVC hMVC hMVC
* Cap Cap Cap]
*/
//[相机id、m_phMVCs、m_pCapInfos] 列向量
if(nrhs != 1) {
mexErrMsgIdAndTxt("MyToolbox:mvc_uinit_camera:nrhs",
"One inputs required.");
}
//无输出
if(nlhs != 0) {
mexErrMsgIdAndTxt("MyToolbox:mvc_uinit_camera:nlhs",
"Zero output required.");
}
if(mxGetM(prhs[0]) != 3){
mexErrMsgIdAndTxt("MyToolbox:mvc_uinit_camera:nlhs",
"Wrong Input.");
}
camera_num = mxGetN(prhs[0]);
pplhs0 = (int*)mxGetData(prhs[0]);
m_phMVCs = (HANDLE*)pplhs0[1];
m_pCapInfos = (struct CapInfoStruct*)pplhs0[2];
for (int i=0;ifree(m_pCapInfos[i].Buffer);
MV_Usb2StartCapture(m_phMVCs[i],FALSE);
MV_Usb2Uninit(&m_phMVCs[i]);
}
free(m_phMVCs);
free(m_pCapInfos);
}
%% MVCInitCamera.m
function mvcMgr = MVCInitCamera( camera_ids,widths,heights,hOffs,vOffs )
if (size(camera_ids,1)~=1)
error('camera_ids should be row vector');
end
camera_num = size(camera_ids,2);
if (length(widths)==1)
widths = ones(1,camera_num)*widths;
heights = ones(1,camera_num)*heights;
hOffs = ones(1,camera_num)*hOffs;
vOffs = ones(1,camera_num)*vOffs;
end
if (camera_num~=size(widths,2) || camera_num~=size(heights,2) || camera_num~=size(hOffs,2) || camera_num~=size(vOffs,2))
error('all the vector should be same size');
end
mvcMgr = mvc_init_camera(camera_ids,widths,heights,hOffs,vOffs );
end
%% MVCGetImage.m
function ims = MVCGetImage( camera_ids,mvcMgr )
ims = mvc_get_image(camera_ids,mvcMgr);
for i=1:length(ims)
ims{i} = rot90(ims{i});
end
end
%% MVCUInitCamera.m
function MVCUInitCamera( mvcMgr )
mvc_uinit_camera(mvcMgr);
end
mex -L. -lMVCAPI mvc_init_camera.cpp
mex -L. -lMVCAPI mvc_get_image.cpp
mex -L. -lMVCAPI mvc_uinit_camera.cpp
源码可从我github仓库下载:https://github.com/liucc09/microview