您的位置:首页 > 编程语言 > MATLAB

Qt+opencv+matlab opencv读写高光谱 .mat文件

2017-03-15 19:38 295 查看
之前用c++处理高光谱数据都是先将数据在matlab里转换为.yml格式再用opencv读取,这样做很麻烦而且效率很低,最近研究混编后开始抛弃以前那些蠢方法。这里分享一下用opencv读写高光谱.mat文件的经验。


1.增加工作路径

opencv的配置这里不再赘述,这里直接讲如何配置matlab库。打开Qt工程在pro里增加matlab的库目录。


INCLUDEPATH +=  D:/MATLAB/R2016a/extern/include
INCLUDEPATH += D:/MATLAB/R2016a/extern/include/win64


LIBS+=-LD:/MATLAB/R2016a/extern/lib/win64/mingw64
-llibmat\
-llibmx\
-llibmex\
-llibeng


2.添加环境变量

在系统环境变量里添加
D:\MATLAB\R2016a\extern\lib\win64\microsoft;
D:\MATLAB\R2016a\bin\win64;


3.在Qt里调用matlab读写文件函数

代码如下,功能:将.mat文件读入opencv Mat结构里,再将opencv Mat结构写到.mat文件输出。

引用matlab头文件

#include <mat.h>
#include <mex.h>


MATFile *pmatFile = NULL;
mxArray *pMxArray = NULL;

//读取高光谱.mat数据
pmatFile = matOpen("D:/Qtcode/Qtone/matlab2_FH/hyper_pavia_double.mat","r");
//读取mat文件中的变量到pMxArray
pMxArray = matGetVariable(pmatFile, "hyper_pavia_double");

//size 存储三维高光谱变量的各维度参数
const size_t *size;
size = mxGetDimensions(pMxArray);
int m_height = *size;//高
int m_width = *(size+1);//宽
int m_channels = *(size+2);//光谱数
int numberOfElements = mxGetNumberOfElements(pMxArray);
int m_imgSize = m_height*m_width;

//mxGetPr获取mat数据指针
double *pMatl = (double*) mxGetPr(pMxArray);
cout<<" "<<m_height<<" "<<m_width<<" "<<m_channels<<" "<<numberOfElements<<" "<<m_imgSize<<endl;

//将数据读入opencv Mat中,注:这里创建的Mat是单通道的,可以用reshape函数转换为多通道
Mat Im(m_imgSize, m_channels, CV_64F);
cout<<"1"<<endl;
for( int x = 0; x < m_width; x++ )
{
for( int y = 0; y < m_height; y++ )
{
int i = y*m_width+x;

double *p = Im.ptr<double>(i);
for( int j = 0; j < m_channels; j++ )
{

p[j] = pMatl[ j*m_imgSize+m_height*x+y ];

}
}
}

matClose(pmatFile);

//创建写数据 dims是写出来的.mat文件中变量 的尺寸
pmatFile = matOpen("D:/Qtcode/Qtone/matlab2_FH/pavia_1.mat","w");
size_t dims[3]={m_height,m_width,m_channels};
pMxArray = mxCreateNumericArray(3,dims,mxDOUBLE_CLASS,mxREAL);
//将opencv Mat数据写到输出文件
double *pOutMatl = mxGetPr(pMxArray);
for( int x = 0; x < m_width; x++ )
{
for( int y = 0; y < m_height; y++ )
{
int i = y*m_width+x;
double *p = Im.ptr<double>(i);
for( int j = 0; j < m_channels; j++ )
{
pOutMatl[ j*m_imgSize+m_height*x+y ] = p[j];
}
}
}
//给输出.mat文件变量命名
matPutVariable(pmatFile, "pavia_1", pMxArray);
matClose(pmatFile);


这里要注意两点。

1、默认.mat的数据格式是double类型,在matlab里先把.mat文件数据类型转换为double在输入。或者把代码里pMatl的指针类型改为和.mat文件相同的类型。不然读取会出错。

2、matlab里数据是按列存储,而c++里数据按行存储,在计算指针是需要注意其区别。

代码里给了简单注释,其它函数的具体的用法请自行在matlab里help并结合实践,这里不复赘述。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息