python 讀取mat文件


需求是提取mat文件里的信息並實時傳到后台服務器,因為matlib的腳本實在太難用,如果只是單純提取信息還可以,

還涉及到一個工程問題,只好用其他語言提取。

同時補充一下這個mat文件的特點,是多層結構,里面有個變量套了多個Cell,重點是解析出多個Cell里的信息,並計算。

開始使用了C#來解析mat文件,因為原來用C#寫過一個自動定時上傳文件的客戶端,稍加改造即可。

但是想當然地又入坑了。

先說C#客戶端,兩個要點

一:多文件傳輸,核心代碼就四行

MultipartFormDataContent multipartFormDataContent = new MultipartFormDataContent(boundary);
var requestUri = "http://XXXXX:8000/imgupload";
multipartFormDataContent.Add(new ByteArrayContent(System.IO.File.ReadAllBytes(file)), "file", uploadfilename);
var result = client.PostAsync(requestUri, multipartFormDataContent).Result.Content.ReadAsStringAsync().Result;

二:定時器,時間可以由用戶指定

timer.Interval = Convert.ToInt32(this.textBox2.Text)*1000;//執行間隔時間,單位為毫秒    
timer.Start();
timer.Elapsed += new System.Timers.ElapsedEventHandler(Timer1_Elapsed);  

以前這個小工具是用來傳圖的,現在改成解析成csv再傳,后台啟了個node服務來接受csv,備份數據后並寫庫。如果實時性要求高可以采用socket-websocket架構方案。

app.post('/imgupload',function(req, res, next){
		var file = req.files;
		var savepath = mypath.parse(file['file']['path']);
		fs.rename(file['file']['path'],mypath.join(savepath.dir,file['file']['originalname']),function(err){
			if(err){
				console.log('上傳失敗');
			}else{
				console.log('上傳成功'+file['file']['originalname']);
			}
		});
		res.send({ret_code: '0'});
	});

 

接下來就是重點了,使用MathNet兩個包來解析mat文件,用VS工具的Nuget包管理器下載Math.net numberics,實在不行百度用install-pacakge裝

using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.Data.Matlab;

發現MathNet.Numerics.Data.Matlab這個4.0版本總是裝不好,報錯,只能安裝到3.2.1版本。

解析數據發現,mat文件的Cell讀不出來,只能讀出個bytesize,一看源碼,還真只有一個bytesize,讀不出內容,github上找了源碼,直接把源碼放到本地,

這些終於有內容了,不過內容好像還是bytesize。。於是只好放棄了這個方案了。。

List<MatlabMatrix> ms = MatlabReader.List(path);
            Matrix<double> StartRanMatrix = MatlabReader.Unpack<double>(ms.Find(m => m.Name == "StartRan"));
            MatlabMatrix TrackMatrix = ms[9];
            string[] read = { "Track" };
            Dictionary<string, Matrix<double>> ms1 = MatlabReader.ReadAll<double>(path, read);
            //找到最低值
            double StartRan = StartRanMatrix.Row(0).First();

過程不表,結局就是Python大法好,真香,里面唯一要注意的是pandas讀取pd.DataFrame 之后求列的均值,

有個很簡單的方法 item.mean(),具體請參考https://blog.csdn.net/tanlangqie/article/details/78656588

下面是python實現讀取解析mat文件的源碼,看看,是不是很優雅,而且執行效率比matlib原生代碼高很多呢~

import pandas as pd
import scipy
from scipy import io
import math
import os

def transformData(path,outputpath):
    features_struct = scipy.io.loadmat(path)
    features = features_struct["Track"]
    StartRan = features_struct["StartRan"][0][0]
    calc = []
    insectNumber = features.size
    for num in range(1,insectNumber):
        dfdata = pd.DataFrame(features[0][num])
        calc.append(dfdata)
    output = []
    count = 1
    for item in calc:
        insectInfo = []
        height = item.mean()
        insectInfo.append(count)
        insectInfo.append(math.floor((height[1]*960/8192+StartRan).real))
        insectInfo.append(math.floor(height[8].real))
        output.append(insectInfo)
        count = count + 1
    outputdata = pd.DataFrame(output)
    outputdata.to_csv(outputpath, index=False)
if __name__ == '__main__':
    rootdir = 'D:\mat'
    folderlist = os.listdir(rootdir)  
    for d in folderlist:
        folder = os.path.join(rootdir, d)
        list = os.listdir(folder) 
        for i in range(0, len(list)):
            path = os.path.join(folder, list[i])
            if os.path.isfile(path):
                str = path.rsplit(".", 1)
                if str[1] == 'mat':
                    output_img_path = str[0] + ".csv"
                    transformData(path,output_img_path)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM