Java读取MAT文件中的三维矩阵

本文主要介绍如何在Java中读取MAT文件数据。

一、matlab保存数据

在matlab中将三维矩阵b保存到文件b.mat中,b三维矩阵如下:
在这里插入图片描述

二、三维矩阵在mat文件中的存储格式

此处不详细讲解mat文件格式,有兴趣可以自行了解:https://www.cnblogs.com/jackcin/p/3416099.html

此处说明三维矩阵是如何在mat文件中存储的。在文件或内存中,我们很容易地根据行和列存储二维矩阵,但是没有很简单的办法存储三维矩阵,所以需要将三维矩阵转换为二维矩阵进行存储。

如果将三维矩阵M[W][H][D]存储为二维矩阵,则根据行优先存储和列优先存储,有以下两种方式:
在这里插入图片描述

在mat文件,采用的是列优先的方式存储三维矩阵。

三、Java读取mat文件

在java中,主要使用以下包来读取mat文件:

jmatio.jar
ujmp-complete-0.3.0.jar

主要通过MatFileReader对象来读取mat文件。

常用方法如下:

  • public MatFileReader(String matfile):构造函数,使MatFileReader对象与mat文件相关联;
  • public MatFileHeader getMatFileHeader():获取mat文件头对象;
  • public Map<String, MLArray> getContent():以map的形式返回mat文件中存在的变量,其中key为变量名,value为变量值;
  • public MLArray getMLArray(String var1):根据mat文件中的变量名返回变量值;

案例:读取之前保存的b.mat文件:

import com.jmatio.io.MatFileHeader;
import com.jmatio.io.MatFileReader;
import com.jmatio.types.MLArray;
import com.jmatio.types.MLDouble;
import com.jmatio.types.MLSingle;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

public class Demo01 {
    public static void main(String[] args) throws IOException {

        File dir = new File("testdata");
        File[] files = dir.listFiles();

        for (File file : files) {
            System.out.println("----------------" + file.getName() + "----------------");

            MatFileReader matFileReader = new MatFileReader("testdata/" + file.getName());
            // 读取MAT Header信息
            MatFileHeader matFileHeader = matFileReader.getMatFileHeader();
            System.out.println("*****mat header*****");
            System.out.println(matFileHeader.toString());

            // 读取矩阵信息,通过矩阵名来获取矩阵信息
            System.out.println("*****mat body*****");

            Map<String, MLArray> content = matFileReader.getContent();

            for (String key : content.keySet()) {
                System.out.println("key=" + key);
                MLArray mlArray = content.get(key);
                System.out.println("value=" + mlArray.toString());
                System.out.println();

                // 转换为java数组
                double[][][] transferMLArray = transferMLArray(mlArray);

                // 打印数据
                int[] dimensions = mlArray.getDimensions();
                for (int k = 0; k < dimensions[2]; k++) {
                    System.out.println("第"+(k+1)+"页数据");

                    for (int i = 0; i < dimensions[0]; i++) {
                        for (int j = 0; j < dimensions[1]; j++) {
                            System.out.print(transferMLArray[i][j][k] + "  ");
                        }
                        System.out.println();
                    }
                    System.out.println();
                }

            }
        }
    }

    /**
     * 将MLArray转换为Java数组
     * @param mlArray
     * @return
     */
    public static double[][][] transferMLArray(MLArray mlArray) {
        int[] dimensions = mlArray.getDimensions();
        double[][][] result = null;
        if (mlArray.isSingle()) {
            System.out.println("mlArray.isSingle()");
            MLSingle mlSingle = (MLSingle) mlArray;
            result = new double[dimensions[0]][dimensions[1]][dimensions[2]];

            for (int i = 0; i < dimensions[0]; i++) {
                for (int j = 0; j < dimensions[1]; j++) {
                    for (int k = 0; k < dimensions[2]; k++) {
                        // 列优先,注意转换
                        result[i][j][k] = mlSingle.get(i, k * dimensions[1] + j);
                    }
                }
            }
        } else if (mlArray.isDouble()) {
            System.out.println("mlArray.isDouble()");
            MLDouble mlSingle = (MLDouble) mlArray;
            result = new double[dimensions[0]][dimensions[1]][dimensions[2]];

            for (int i = 0; i < dimensions[0]; i++) {
                for (int j = 0; j < dimensions[1]; j++) {
                    for (int k = 0; k < dimensions[2]; k++) {
                        // 列优先,注意转换
                        result[i][j][k] = mlSingle.get(i, k * dimensions[1] + j);
                    }
                }
            }
        }

        return result;
    }
}

结果:
在这里插入图片描述

四、参考资料

[1]https://www.jianshu.com/p/7fb1d0169687

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值