C++开发-matio库安装(VS2022)

主要参考:https://blog.csdn.net/weixin_73535565/article/details/140566000

matio库主要用于在cpp中读取在matlab保存的mat文件,我这里用于读取mat中的矩阵和cell。

下载提醒:如果遇到下载慢的情况可以选择把猫猫的模式从rule改为global。

编译工具安装

使用cmake作为编译工具,地址:https://cmake.org/download/

根据自己电脑是64位还是32位选择installer,我电脑是x64,所以选择cmake-3.30.1-windows-x86_64.msi

下载之后双击msi,根据指示安装完成。

HDF5库和zlib库编译安装

matio主要依赖HDF5和zlib这两个库,所以在编译安装matio之前需要先安装这两个库。

HDF5库编译安装

HDF5官网,先别点进去:https://www.hdfgroup.org

HDF5库的1.14版本没有提供Cmake版本,所以需要选择之前的1.12版本,

地址:https://portal.hdfgroup.org/downloads/hdf5/hdf5_1_12_3.html

下载地址:https://hdf-wordpress-1.s3.amazonaws.com/wp-content/uploads/manual/HDF5/HDF5_1_12_3/src/hdf5-1.12.3.zip

下载之后解压到一个不会被删除的地方,我不小心放在了下载文件夹下,不要学我。

解压之后根据VS版本双击bat文件运行(确保cmake已经安装,不然会直接闪退)

需要时间挺久的,运行之后窗口会自动退出。之后双击HDF5中新增的build文件夹中的HDF5.sln,进入VS

进入VS后确认一下是release还是debug,HDF5和zlib需要在同一模式下编译安装。release比较快,所以我这里选择release x64

右键ALL_BUILD,点击生成,如果之前由于各种原因生成失败的话可以右键ALL_BUILD-重新生成。ALL_BUILD生成成功之后右键INSTALL-生成,成功的话在输出中可以看到installing的位置,记录一下位置,之后要用。

zlib库编译安装

zlib库地址,不用点进去:http://www.zlib.net/

不用特地去下载,因为在HDF5文件夹里有zlib-1.3.tar.gz,一样解压到不会被删除的地方

在zlib文件夹下新建一个build文件夹,然后打开cmake(cmake-gui)

选择zlib路径和zlib中的build路径,勾选Grouped和Advanced,点击configure,在弹出来的窗口选择VS版本和系统位数,如果是VS2022和x64就可以直接点击finish。

修改INSTALL的路径,全部选择新建的build/xxx内,具体路径如图所示,选择好之后点击configure generate,不出问题之后点击open project,之后会自动打开VS。

和HDF5的步骤一样,在release x64模式下,右键ALL_BUILD-生成,之后右键INSTALL-生成,在输出里记录一下installing的地址,一会要用。

matio编译安装

matio库安装地址:https://github.com/tbeu/matio

下载并解压到一个不会被删除的地方,打开cmake,选择matio路径和里面的build路径

点击configure,会报错是正常的,因为路径还没选择,需要路径选择如下,仅供参考,可以搜索一下HDF5中具体的文件夹在哪,比如include

HDF5路径选择好之后点击configure,再次报错,这次需要选择zlib路径,具体如下

点击configure generate,这次应该不会报错,点击open project,和上面一样,右键ALL_BUILD-生成,右键INSTALL-生成

如果有以下报错,那么请把当前VS关掉,然后以管理员身份打开VS,选择matio.sln,右键ALL_BUILD-重新生成,右键INSTALL-重新生成,然后应该没有问题了。记录一下installing的位置,一会要用。

添加环境变量

任务栏搜索环境变量-点击编辑系统环境变量-点击环境变量-双击系统变量中的Path-点击右上角新建-添加这三个库的路径,路径都是不同的,但是位置的后半段应该是一样的。

在VS项目中附加matio库

右键项目(我这里是CMM)-属性-c/c++-附加包含目录,添加以下路径

C:\Program Files (x86)\matio\include

还是属性-链接器-输入-附加依赖项,添加以下路径

C:\Program Files (x86)\matio\lib\libmatio.lib

至此matio安装完毕

cpp读取mat中的cell和矩阵

需要事先添加Eigen库,添加过程略。

openMatFile用来读取矩阵,openCellFile用来读取cell中的矩阵,我这里是756*756的cell,每个cell元素是一个n*m的矩阵,读取之后为std::vector<std::vector<MatrixXd>>的变量。

#include <iostream>
#include <vector>
#include <matio.h>
#include <Eigen/Dense>

using Eigen::MatrixXd;
using namespace std;

bool openMatFile(const std::string& filePath, MatrixXd& eigenMatrix)
{
    mat_t* pMatFile = nullptr;   // MAT文件句柄
    matvar_t* pMatVar = nullptr; // MAT文件中的变量
    double* data = nullptr;   // 存储矩阵数据的指针
    int numRows, numCols;     // 矩阵的行数和列数

    // 打开mat文件
    pMatFile = Mat_Open(filePath.c_str(), MAT_ACC_RDONLY); // matOpen 函数打开MAT文件
    if (!pMatFile)
    {
        std::cerr << "Failed to open MAT file" << std::endl;
        return false;
    }

    // 遍历所有变量
    pMatVar = Mat_VarReadNext(pMatFile);
    while (pMatVar)
    {
        // 输出变量信息
        std::cout << "Variable name: " << pMatVar->name << std::endl;
        std::cout << "Variable rank: " << pMatVar->rank << std::endl;
        std::cout << "Variable dimensions: ";
        for (int i = 0; i < pMatVar->rank; ++i)
        {
            std::cout << pMatVar->dims[i] << " ";
        }
        std::cout << std::endl;

        // 处理二维双精度矩阵
        if (pMatVar->class_type == MAT_C_DOUBLE && pMatVar->rank == 2)
        {
            numRows = pMatVar->dims[0];
            numCols = pMatVar->dims[1];
            data = static_cast<double*>(pMatVar->data);

            // 将数据复制到Eigen矩阵
            eigenMatrix.conservativeResize(numRows, numCols);
            int i = 0;
            for (int c = 0; c < numCols; ++c)
            {
                for (int r = 0; r < numRows; ++r)
                {
                    eigenMatrix(r, c) = data[i];
                    ++i;
                }
            }

            //std::cout << "Read matrix: " << pMatVar->name << std::endl;
            //std::cout << eigenMatrix << std::endl;
        }


        // 释放当前变量
        Mat_VarFree(pMatVar);
        pMatVar = nullptr;

        // 继续遍历下一个变量
        pMatVar = Mat_VarReadNext(pMatFile);
    }

    // 关闭mat文件
    Mat_Close(pMatFile);
    pMatFile = nullptr;
    std::cout << "File closed" << std::endl;
    return true;
}

bool openCellFile(const std::string& filePath, std::vector<std::vector<MatrixXd>>& output)
{
    mat_t* pMatFile = nullptr;   // MAT文件句柄
    matvar_t* pMatVar = nullptr; // MAT文件中的变量
    double* data = nullptr;   // 存储矩阵数据的指针
    int numRows, numCols;     // 矩阵的行数和列数

    // 打开mat文件
    pMatFile = Mat_Open(filePath.c_str(), MAT_ACC_RDONLY); // matOpen 函数打开MAT文件
    if (!pMatFile)
    {
        std::cerr << "Failed to open MAT file" << std::endl;
        return false;
    }

    // 遍历所有变量
    pMatVar = Mat_VarReadNext(pMatFile);
    while (pMatVar)
    {
        // 输出变量信息
        std::cout << "Variable name: " << pMatVar->name << std::endl;
        std::cout << "Variable rank: " << pMatVar->rank << std::endl;
        std::cout << "Variable dimensions: ";
        for (int i = 0; i < pMatVar->rank; ++i)
        {
            std::cout << pMatVar->dims[i] << " ";
        }
        std::cout << std::endl;

        // 获取cell数组的尺寸
        size_t numRows = pMatVar->dims[0];
        size_t numCols = pMatVar->dims[1];
        output.resize(numRows, std::vector<MatrixXd>(numCols));

        // 遍历cell数组中的每个元素
        matvar_t** cells = (matvar_t**)pMatVar->data;
        cell也是纵着读的,ij需要互换
        for (size_t i = 0; i < numRows; ++i)
        {
            cout << i << endl;
            for (size_t j = 0; j < numCols; ++j)
            {
                matvar_t* pCell = cells[i * numCols + j];
                if (pCell->class_type == MAT_C_DOUBLE && pCell->rank == 2)
                {
                    // 读取矩阵数据
                    size_t rows = pCell->dims[0];
                    size_t cols = pCell->dims[1];
                    double* data = static_cast<double*>(pCell->data);

                    MatrixXd matrix(rows, cols);
                    int index = 0;
                    for (size_t r = 0; r < rows; ++r)
                    {
                        for (size_t c = 0; c < cols; ++c)
                        {
                            matrix(r, c) = data[r + c*rows];
                        }
                    }

                    output[j][i] = matrix;
                }
            }
        }
        /*MatrixXd matrix = output[169][6];

        cout << matrix << endl;*/

        // 释放当前变量
        Mat_VarFree(pMatVar);
        pMatVar = nullptr;

        // 继续遍历下一个变量
        pMatVar = Mat_VarReadNext(pMatFile);
    }

    // 关闭mat文件
    Mat_Close(pMatFile);
    pMatFile = nullptr;
    std::cout << "File closed" << std::endl;
    return true;
}

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值