2013年9月9日 星期一

Matlab入門課程(3)字串處理

之前在FORTRAN入門課程裡面談到字串處理功能最容易被人忽視,Matlab何嘗不是呢?大家都以為Matlab最詭異的功能,也最容易被「經常作矩陣運算的人」所忘記的功能就是字串處理功能,這種經常在其他語言中看到的功能,卻很少被寫FORTRAN或者Matlab的人重視。
因為,寫FORTRAN/Matlab的人不會想到從一堆雜亂的資料中,挖出自己想要的內容, 可能情願自己打一個簡單清楚的資料檔,或者用記事本、Execl先把資料處理處理,在拿給Fortran/Matlab程式讀取使用。
 例如,有一個ENVI軟體產生的header,其內容如下

ENVI
description = {
  Create New File Result [Fri Jul 22 14:32:54 2005]}
samples = 5760
lines   = 9092
bands   = 4
header offset = 0
file type = ENVI Standard
data type = 2
interleave = bsq
sensor type = Unknown
byte order = 0
map info = {UTM, 1.000, 1.000, 231562.584, 2598337.772, 
1.0000000000e+000, 1.0000000000e+000, 51, North, WGS-84, units=Meters}
wavelength units = Unknown
pixel size = {1.00000000e+000, 1.00000000e+000, units=Meters}

上面這個檔案是由ENVI自動產生,其中samples=5760表示影像矩陣的nx大小,
lines=9092表示影像矩陣的ny大小,我們該如何讀出這二個值呢?

function envi_header
 fid=open('envi_image.hdr','r')
  % 跳過3列資料
  tline=fgetl(fid);
  tline=fgetl(fid);
  tline=fgetl(fid);
  % 將資料讀入 aLine 字串變數.
  tline=fgetl(fid);
  % 算出等號之後一位的位置
   n=strfind(tline,'=')+1;
  % 從等號之後一位的位置到第最後一個字元讀入nx
  nx=sscanf(tline(n:end),'%d');

  tline=fgetl(fid);
  % 算出等號之後一位的位置
   n=strfind(tline,'=')+1;
  % 從等號之後一位的位置到第最後一個字元讀入nx
  ny=sscanf(tline(n:end),'%d');
fclose(fid); disp(['nx,ny=' num2str(nx) ', ' num2str(ny)]) % 動態配置矩陣. red=uint8(zeros(nx,ny));
        green=uint8(zeros(nx,ny));
        blue=uint8(zeros(nx,ny));

......


2013年9月8日 星期日

Matlab入門課程(1)解決最簡單的問題

前幾天,碰到一位同學來詢問我有關簡單的資料處理問題,討論完演算法之後,問他打算用什麼語言來寫,他很靦腆的說C++。我說用Matlab就可以了,不必用到C++吧?

大家或許覺得Matlab只適合在校園使用,所以,在學生時代就會勉勵自己要用未來可以找到工作的程式語言來寫,有關這一點,我並不反對。

但是,如果一個簡單的問題,要花掉好多時間去處理,連畢業都有困難,還擔心畢業以後的事情嗎?我建議先把資料處理的基本功夫學好,再談用C++開發大型的系統。

這一篇文章是延續 FORTRAN入門課程(1)解決最簡單的問題 同樣的內容,只是用Matlab來寫

fid1=fopen('data.xyz','r');
fid2=fopen('new_data.xyz','w');
        while 1
            tline = fgetl(fid1);
            if ~ischar(tline), break, end
            A=sscanf(tline,'%f, %f,%f');
            x=A(1); y=A(2); z=A(3);
            fprintf(fid2,'%f,%f,%f\r\n',x,y,-z);
        end
fclose(fid1);
fclose(fid2);

這個程式使用下列幾個Matlab基本的觀念

  • 檔案開啟(fopen)與關閉(fclose)
  • 檔案讀取(fgetl)與寫入(fprintf)
  • 字串處理(sscanf)
  • 迴圈(while loop)
  • 決策(if)
這個程式的基本精神是用fgetl函數將整列資料當成字串,讀入tline字串變數中
再用sscanf函數,將x,y,z三個變數讀入A矩陣中,在輸出的時候,才改變z的符號