因為Matlab操作簡單、方便,它被應用於很多領域:音頻處理,圖像處理,數值計算等。盡管MATLAB容易操作,但受限於他的語言解釋機制,MATLAB的執行速度通常較低。C/C++一般被認為是執行較為高效的高級程序設計語言。如果結合MATLAB和C/C++,也許我們可以獲得操作簡便性和執行速度的折中。這種結合的一般形式是:MATLAB負責絕大部分工作,C/C++負責一些關鍵部分的實現,其具體方法在我之前的博文中已經有所介紹。
在處理某些數據的時候,可能涉及到文件的讀寫,如果用MATLAB存儲為mat文件,那麼其它程序讀取這種數據就變得困難了。如果將數據存為文本文件,文件的解析過程就會變得比較長。幸運的是MATLAB可以讀寫自定義格式的二進制文件,基本所有程序語言(包括C/C++)在內,都是支持二進制文件的讀寫操作的。本文就介紹一下如何使用MATLAB和C/C++對二進制文件進行讀寫。
MATLAB和C/C++並不采用相同的規則來存儲矩陣數據!在聯合MATLAB和C/C++時,一定要注意這一點:C/C++按行存儲數據;MATLAB按列來存儲數據。舉例說明,假設我們有一個2行3列的矩陣,共2
MATLAB提供了四個函數來讀寫二進制文件:fopen(...)
, fread(...)
, fwrite(...)
, fclose(...)
.
舉例說明如何對二進制文件進行讀寫操作:
實例1:將雙精度矩陣以單精度浮點數類型存入二進制文件
% 生成一個2行3列的雙精度浮點數類型的矩陣
A = rand(2,3);
% 在當前工作目錄下以二進制寫方式 ('w') 打開'test.dat'
fid = fopen('test.dat', 'w');
% 將矩陣A的元素以單精度浮點數類型寫如fid關聯的二進制文件
fwrite(fid, A, 'single');
% 將與fid關聯的文件關閉
fclose(fid);
實例 2:以單精度浮點數類型讀入MATLAB
% 在當前工作目錄下以二進制讀方式 ('r') 打開'test.dat'
fid = fopen('test.dat', 'r');
% 從與fid關聯的二進制文件讀取6個元素,每個元素以單精度浮點類型解析
B = fread(fid, 2*3, 'single');
% 將與fid關聯的文件關閉
fclose(fid);
實例2中,B是一個6B = reshape(B, 2, 3)
C讀取二進制數據的方式與MATLAB類似。
實例 3: 用C語言讀取實例 1 的test.dat
// 完整的C代碼
#include
#include
int main(){
int i;
char *filename = "test.dat";
float data[6];
FILE *fs = fopen(filename, "r");
fread((void*)data, sizeof(float), 6, fs);
fclose(fs);
// 顯示數據
for (i = 0; i < 6; i++){
printf("%f\n", data[i]);
}
return 0;
}
實例 3 的輸出結果跟實例 2 中讀取的B的結果是一致的。如果對實例 2 中的B用MATLAB進行reshape操作,B就會變成跟實例 1 中的A類似的存儲結構,A和B的差別只在於他們的數據類型不同。實例 3 中使用data的時候,如果要想跟MATLAB一樣索引第 i 行 第 j 列的元素,則必須轉置訪問!
如果在C中有大量的後續操作,並且你的大部分重要工作用C來完成的話,建議在MATLAB中的寫操作可以將矩陣變換行列(不是共轭轉置)後再做寫入,修改如下:
fwrite(fid, A.', 'single');
用C++讀二進制文件需要fstream類,實例如下:
實例 4 : 用C++ 讀取實例 1 寫入的test.dat
// 完整C++代碼
#include
#include
#include
using namespace std;
int main(){
float data[6];
string filename = "test.dat";
ifstream fs;
fs.open(filename, ios_base::binary | ios_base::in);
fs.read(reinterpret_cast(data), sizeof(float)* 6);
fs.close();
for (int i = 0; i < 6; i++){
cout << data[i] << endl;
}
return 0;
}
使用MATLAB和C/C++可以較快的完成算法的開發的同時,獲得一個較快執行速度的程序。
在聯合使用MATLAB和C/C++時,一定要注意數據的存儲順序。