Python读取与保存MATLAB .mat数据及类型转换避坑指南
本文详解Python中利用scipy和h5py库读取及保存MATLAB .mat数据的方法。重点解决savemat需传入字典格式的问题,并深入分析uint8数据在Python与Matlab运算中的溢出差异。通过对比int8与float类型转换结果,推荐在涉及图像加减运算时使用float格式以保证精度,避免数据错误。
处理matlab的mat数据
Python和Matlab是实验室中常用的两种平台工具。在实际应用中,经常需要在这两个平台之间交换数据,因此掌握数据的读取与保存方法至关重要。这通常需要借助Python第三方库中的scipy模块来实现。
首先,使用以下命令检查是否已安装scipy库。
import scipy若安装失败或报错,可通过执行python install scipy或conda install scipy命令进行下载安装。
在scipy模块中,主要使用输入输出类提供的loadmat和savemat方法来进行数据的加载与保存操作。
import scipy.io as sio
sio.loadmat(file_name, mdict=None, appendmat=True, **kwargs)
sio.savemat(file_name, mdict, appendmat=True, format='5', long_field_names=False, do_compression=False, oned_as='row'
下面介绍一个常见的错误示例:savemat方法要求传入的参数必须为字典格式。
import scipy.io as sio
import numpy as np
x = np.ones((3,3))
x
Out[86]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
sio.savemat('f.mat',x)
Traceback (most recent call last):
File "<ipython-input-87-d739bc03c885>", line 1, in <module>
sio.savemat('f.mat',x)接下来展示一个简单的保存与导入示例。
import scipy.io as sio
import numpy as np
x = np.ones((3,3))
x
Out[86]:
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
sio.savemat('f.mat',{"x":x})
myMat =sio.loadmat('f.mat')
print(myMat) #输出为字典
{'__header__': b'MATLAB 5.0 MAT-file Platform: nt, Created on: Fri Aug 21 16:29:37 2020', '__version__': '1.0', '__globals__': [], 'x': array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])}
#以保存名为key,输出list value
print(myMat['x'])
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]若希望将Python数据保存为mat格式,由于Python原生不支持cell格式,而mat文件可能包含cell数据,因此需要借助numpy模块进行处理,具体可参考相关技术博客。
处理matlab的*.mat格式数据及常见错误汇总
由于Matlab和Python的编程逻辑存在差异,在混合编程时,常需利用Python调用Matlab格式的数据。下文将介绍如何调用mat格式数据以及常见错误的解决方法,供参考。
一、数据读取错误
# 最初用loadmat读取数据
import numpy as np
from scipy.io mport loadmat
img = loadmat('im.mat')['im'] #im.mat为mat数据的名称,['im'] 中的im表示该文件下im的数据
使用上述代码读取数据时,可能会遇到如下错误提示。

若出现上述错误,建议改用以下方式读取数据。
import h5py
img = h5py.File('im.mat')['im']
img = h5py.File('im.mat','r')['im'] # 无警告
二、数据类型错误
在使用Python处理图像时,若涉及加减运算,因数据类型限制导致的溢出值可能会被重新赋值为255或0。
# python代码
import h5py
import numpy as np
img = h5py.File('im.mat')['im']
# python中的M,N刚刚好与matlab中的M,N取值相反,此处进行转置与matlab相同矩阵格式进行处理
x = np.array(img).T
[M, N] = x.shape
if M < 16 and N < 16:
score = -2
# Feature Extraction:
# 1. horizontal features
d_h = x[:, 1:N] - x[:, 0:N - 1] # 该步操作图像产生满溢,溢出后差值可能都被赋为255,依次递减
这种情况下,d_h数据会出现满溢现象。下面展示了相同数据在Python和Matlab环境下运算结果的差异。

% Matlab 代码
img = laod('im.mat')
[M, N] = size(x)
if M < 16 | N < 16
score = -2;
end
x = double(img); % 将无符号类型uint8数据类型转换为double类型
% Feature Extraction:
% 1. horizontal features
d_h = x(:, 2:N) - x(:, 1:(N-1));

原因分析:导入的数据类型为uint8格式,该格式不支持负数。在Matlab中进行运算时,系统会自动将uint8类型转换为double类型后再进行减法运算,因此结果正常。但在Python中,由于没有自动转换机制,需手动设置数据类型。只需将数据类型改为非uint8格式即可(具体格式需根据需求确定,此处修改为int8格式)。解决方法非常简单,只需在读取代码的一行中加入数据类型指定即可。
x = np.array(img,dtype = 'int8').T # 对读取的uint8格式数据进行重新定义一下格式即可
x = np.array(img,dtype = 'float').T # 下面这种格式虽然是浮点型,但是计算过程不容易出错,如果是上面的int8会出现部分错误,需要注意
现在查看结果,处理效果与Matlab一致。

虽然下方示例使用的是浮点型,但能确保数据转化的精度和准确性,img影像数据转化为数值时不会出错。非必要情况下,不建议使用int8数据格式,因为int8在某些部分可能出现错误,这一点务必注意。例如在改组数据中,坐标(0,80)处的数值在int8格式转化时出错,原始数值为129,转化后变为127;而使用float格式则不会出现此类错误。

原始数据为uint8格式,数值为129。在Python中,不同格式类型的值表现各异。

因此,uint8格式在Python运算中转换为float格式更为可靠,转换为int8格式则容易产生问题。
以上为个人经验分享,希望能为大家提供参考,也希望大家多多支持本站。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









