基礎(chǔ)知識
有關(guān).mat文件,是matlab中的基本文件格式。這個格式主要用來存放matrix,即圖像中各個像素點(diǎn)的值。但是.mat文件不能直接通過FileReader進(jìn)行讀取,如果想要在matlab中引用.mat可以直接使用load來加載代碼:
load(filepath\filename.mat)
圖像處理中會涉及的mat文件格式最后會在由于筆者不能熟練掌握matlab的基本語法,因此使用java來進(jìn)行.mat文件的讀寫。但是.mat文件格式不能直接用輸入流,因此只能用特殊的jar包來進(jìn)行讀。介紹一下jmatio。
jmatio基本知識
jmatio用于java讀取.mat文件的矩陣,通過jar包配置的方式來進(jìn)行。筆者沒有用過maven,因此直接引用了jar包。
可以看到建立了lib文件,同時引入這兩個jar包,直接去官網(wǎng)下載即可,不多做介紹:
建立完成后,在Idea中配置ProjectStructure,左上角菜單file下拉就可以看到ProjectStructure了:
配置完成,如果MatFileReader和MLArray能夠正常導(dǎo)入,那么就說明配置正確了。建議下載ujmp-complete-0.3.0.jar版本,至少用到現(xiàn)在沒有出錯。主要使用的三個基本類:
import com.jmatio.io.MatFileReader;
import com.jmatio.types.MLArray;
import com.jmatio.types.MLDouble;
讀取三維矩陣
很遺憾,由于jmatio用的人非常少,因此很難查到相關(guān)資料。網(wǎng)上幾乎所有的例子都是二維矩陣,然而筆者做的項目是一個空間三維的建模。摸索之后大概清楚了應(yīng)該怎樣能正確讀取三維矩陣。
讀取.mat文件使用MatFileReader類,代碼如下:
MatFileReader read = new MatFileReader("data/seg1.mat");//throw IOException
MLArray mlArray = read.getMLArray("I_Global");//配置文件讀取出來后的變量名為I_Global
需要引入維度方法getDimensions()這個方法返回的是維度大小size()的向量。如果要查看導(dǎo)入的代碼有幾行,使用getNDimensions()執(zhí)行。本例中的三維矩陣mlArray對應(yīng)的矩陣維度是mlArray.getNDimensions() == 3,同理需要查看每一維的大小使用代碼:
sizex = mlArray.getDimensions()[0];
sizey = mlArray.getDimensions()[1];
sizez = mlArray.getDimensions()[2];
由于jmatio只能支持二維矩陣的正常讀取工作,因此mlArray.get(var1, var2)這個方法只能支持兩個參數(shù)。因此實際的矩陣維度并不是sizex*sizey*sizez而是sizex*(sizey*sizez),如果需要拆分第二和第三維必須要知道實際的mlArray中矩陣第二維的組織形式。
這里有個大坑,第二維的組織方式并不是像一般情況下先組織第三維再組織第二維的,直觀來說就是和我們的思路反了。一般來說,如果要把一個二維矩陣給轉(zhuǎn)換為一維矩陣,那么坑爹的jmatio是這么做的:
代碼如下:
MLDouble d = (MLDouble)mlArray;//轉(zhuǎn)換為MLDouble類型
for (int i = 0; i < d.getDimensions()[0]; i++)
for (int j = 0; j < d.getDimensions()[1]; j++)
for (int k = 0; k < d.getDimensions()[2]; k++) {
//先考慮第二維,再考慮第三維
matResult[i][j][k] = d.get(i, k * d.getDimensions()[1] + j);
}
通過測試,結(jié)果正確。這樣返回的matResult就是正確存儲的三維數(shù)組了。
引用一下kaggle中大佬的評價:
I see that the MAT file format is not so easy to read from Java - and maybe from some other languages too, e.g. C++. The main issue is that the MEG measurements ("X") are shaped into a 3D data matrix. For this reason I am preparing simple Python code to transform MAT files into more standard (but much bigger!) CSV files. So the idea would be to download the compact zip/mat files, and then to run this converter on your local machine to get the CSV files. I will post more information later, as soon as the code is ready. Of course this procedure will assume that you can run a simple Python script and have SciPy installed (necessary to have the function loadmat()).
My attempt is not much different from that of Triskelion which provided a converter to the Vowpal Wabbit format or that of robstr in another thread of this forum. But I think that CSV format is more standard and it is supported by any language. Moreover I think that having more options is better.