前言:在进行图形图像处理时,经常会用到matlab进行算法的仿真验证,然后再移植到别的语言中。有时会涉及到数据的交互,比如直接读取matlab的.mat类型数据,或者是将c++中的数组存为.mat,为了使用方便,这里介绍一下c++对.mat的读写。

一、工程配置:

1、附加包含目录:
D:\MATLAB\extern\include

2、附加库目录:

D:\MATLAB\extern\lib\win64\microsoft

3、附加依赖库:
libmat.lib
libmx.lib
libmex.lib
libeng.lib

4、计算机环境变量->path 添加:

D:\MATLAB\bin\win64;

5、其他:

  • 上述路径应改为自己的路径。
  • C++工程解决方案平台应与matlab版本一致

二、存储.mat

直接上代码:

#include <string.h>
#include <iostream>
#include <stdio.h>
#include <mat.h>
using namespace std; template<typename T>
bool SaveMatlabMat(T *src,string savePath,string matrixName,int width,int height)
{
//转置存储
int datasize = width * height;
double *Final = new double[datasize];//待存储数据转为double格式
memset(Final, , datasize * sizeof(double));
for (int i = ; i < height; i++)
{
for (int j = ; j < width; j++)
{
Final[i*width+j] = double(src[i*width+j]);
}
}
mxArray *pWriteArray = NULL;//matlab格式矩阵
MATFile *pmatFile = NULL;//.mat文件指针
pmatFile = matOpen(savePath.c_str(), "w");
if (pmatFile == nullptr)
{
printf("mat save path is error");
return false ;
}
//创建一个width*height的矩阵
pWriteArray = mxCreateDoubleMatrix(width, height, mxREAL);
//把data的值赋给pWriteArray指针
memcpy((void *)(mxGetPr(pWriteArray)), (void *)Final, sizeof(double) * datasize);
//给矩阵命名为matrixName
matPutVariable(pmatFile, matrixName.c_str(), pWriteArray);
matClose(pmatFile);
mxDestroyArray(pWriteArray);//release resource
delete[]Final;//release resource return true;
} int main()
{
int width=;
int height=;
int *array = new int[width*height];//初始化一个height*width的二维矩阵
memset(array,,sizeof(int)*width*height);
for (int i = ; i < height; i++)
{
for (int j = ; j < width; j++)
{
array[i*width + j] = i*width + j;
}
}
string filePath = "aa.mat";//文件名字
string matrixName = "aa";//文件内矩阵名
SaveMatlabMat(array,filePath, matrixName,width,height); return ;
}

  代码运行完会在当前目录下发现“aa.mat”文件,用matlab打开后如下图所示:

  可以发现与c++中矩阵为转置关系,这是因为matlab中的数据是按列存储的,而c++中是按行存储的。前面我初始化的c++矩阵中第一行为0~2591,在matlab中存为第一列。这在实际使用中很不方便,为了消除这种转置关系,我们只需在把数据存入Final时提前进行转置,附上代码如下:

template<typename T>
bool SaveMatlabMat(T *src, string savePath, string matrixName, int width, int height)
{
//转置存储
int datasize = width * height;
double *Final = new double[datasize];//待存储数据转为double格式
memset(Final, , datasize * sizeof(double));
for (int i = ; i < height; i++)
{
for (int j = ; j < width; j++)
{
Final[j*height+i] = double(src[i*width + j]);
}
}
mxArray *pWriteArray = NULL;//matlab格式矩阵
MATFile *pmatFile = NULL;//.mat文件指针
pmatFile = matOpen(savePath.c_str(), "w");
if (pmatFile == nullptr)
{
printf("mat save path is error");
return false;
}
//创建一个height*width的矩阵
pWriteArray = mxCreateDoubleMatrix(height, width, mxREAL);
//把data的值赋给pWriteArray指针
memcpy((void *)(mxGetPr(pWriteArray)), (void *)Final, sizeof(double) * datasize);
//给矩阵命名为matrixName
matPutVariable(pmatFile, matrixName.c_str(), pWriteArray); matClose(pmatFile);//close file
mxDestroyArray(pWriteArray);//release resource
delete[]Final;//release resource return true;
}

这样,便使得写入的.mat文件和c++矩阵格式保持一致。

三、读取.mat

  与写入一样,由于matlab按列存储数据,c++读取时也是读取matlab的第一列数据,因此读取时也要考虑转置关系,这里直接附上代码,读取我们刚刚存储的aa.mat。

template<typename T>
bool ReadMatlabMat(T *dst, string filePath,string matrixName, int width, int height)
{
MATFile *pmatFile = NULL;
mxArray *pMxArray = NULL;
double *matdata;
pmatFile = matOpen(filePath.c_str(), "r");//打开.mat文件
if (pmatFile == NULL)
{
printf("filePath is error");
return false;
}
pMxArray = matGetVariable(pmatFile, matrixName.c_str());//获取.mat文件里面名为matrixName的矩阵
matdata = (double *)mxGetData(pMxArray);//获取指针
matClose(pmatFile);//close file for (int i = ; i < height; i++)
{
for (int j = ; j < width; j++)
{
dst[i*width+j] = T(matdata[j*height + i]);
}
}
mxDestroyArray(pMxArray);//释放内存
matdata = NULL;
return ;
}

c++读写matlab中.mat数据的更多相关文章

  1. 两分钟解决Python读取matlab的.mat数据

    Matlab是学术界非常受欢迎的科学计算平台,matlab提供强大的数据计算以及仿真功能.在Matlab中数据集通常保存为.mat格式.那么如果我们想要在Python中加载.mat数据应该怎么办呢?所 ...

  2. matlab中mat文件简单存/取

    >>abc=[,,,,,]; >>save data save file_name:命令可以将当前项目中变量的值保存到file_name中去,这里的data文件就是mat文件. ...

  3. matlab中图片数据类型转换uint8与double

    matlab中处理图像像素点数据: img1=double(imread('lenna.bmp')); matlab中imshow图片,要先转换成uint8: subplot(1,2,1),imsho ...

  4. C#实现读写文本文件中的数据

    [1]首先我们定义一段假数据,这里以一个string为例字 static void Main(string[] args)        {            string data = &quo ...

  5. MATLAB中导入数据:importdata函数

    用load函数导入mat文件大家都会.可是今天我拿到一个数据,文件后缀名竟然是'.data'.该怎么读呢? 我仅仅好用matlab界面Workspace区域的"import data&quo ...

  6. OpenCV中Mat数据的访问报错

    最近再写一段程序的时候,要访问Mat中的元素.在定义Mat型数据的时候,用 Mat ObjectPoints(48,3,CV_32FC1,0) 对其进行初始化后,用at进行访问时报内存错误. Mat ...

  7. 【转】Java读取matlab的.mat数据文件

    参考:Java读取mat文件 下载链接:ujmp  jmatio 下载完两个.jar文件之后,如何引用到java项目当中?项目名称->右键->Property->Java Build ...

  8. 利用java反射读写csv中的数据

      前一段有个需求需要将从数据库读取到的信息保存到csv文件中,在实现该需求的时候发现资料比较少,经过收集反射和csv相关资料,最终得到了如下程序.  1.在使用java反射读取csv文件数据时,先通 ...

  9. 使用json读写文件中的数据

    把json的数据写入到文件中 import json with open('data.json','w+') as f: json.dump({"name":"张彪&qu ...

随机推荐

  1. Python之虚拟环境virtualenv、pipreqs生成项目依赖第三方包

    virtualenv简介 含义: virtual:虚拟,env:environment环境的简写,所以virtualenv就是虚拟环境,顾名思义,就是虚拟出来的一个新环境,比如我们使用的虚拟机.doc ...

  2. TCP/IP详解 IP路由选择

    TCP/IP详解 IP路由选择 在本篇文章当中, 将通过例子来说明IP路由选择器过程 如图所示, 主机A与主机B分别是处在两个不同的子网当中, 中间通过一个路由连接. 如果主机A请求与主机B进行通行, ...

  3. Android 系统架构 和 各个版本代号介绍

    一.Android 系统架构: 1. linux内核层Android 基于Linux内核,为Android设备的各种硬件提供底层驱动 比如: 显示驱动.音频.照相机.蓝牙.Wi-Fi驱动,电源管理等 ...

  4. mysql中length与char_length字符长度函数使用方法

    在mysql中length是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符了,与char_length是有一点区别,本文章重点介绍第一个函数. mysql里面的length函数是一个用来 ...

  5. ChineseNumber 转换

    中文数字转换 /** * <html> * <body> * <P> Copyright 1994 JsonInternational</p> * &l ...

  6. C#获取文件夹下的所有文件的方法

    目录 #基础知识 #只获取目录下一级的文件夹与文件 # 递归地输出当前运行程序所在的磁盘下的所有文件名和子目录名 正文   #基础知识 1.获得当前运行程序的路径 1 string rootPath ...

  7. java基础 Arrays

    package cn.mantishell.day08.demo04; import java.util.Arrays; /** * java.util.Arrays是一个与数组相关的工具类,里面提供 ...

  8. HDU2476 String painter(DP)

    题目 String painter 给出两个字符串s1,s2.对于每次操作可以将 s1 串中的任意一个子段变成另一个字符.问最少需要多少步操作能将s1串变为s2串. 解析 太妙了这个题,mark一下. ...

  9. P1361 小M的作物 (最大流)

    题目 P1361 小M的作物 解析 把\(A\)看做源点,把\(B\)看做汇点,先不考虑额外情况 显然,这是一种两者选其一的问题,我们选择一部分边割去,使这部分边的贡献最小,就是求最小割,我们求出了收 ...

  10. Laravel 5.5 发布,ThinkSNS+ 升级及状况分享

    升级场景 ThinkSNS+ 一直依赖,都是保留 Laravel 的 commit 记录的前提下,进行开发,为了追随 Laravel 的升级,我们在本地的仓库中新建了一个分支,如果 laravel 更 ...