数値解析法及び演習 第十四回

画像解析
  1. 画像の表現
  2. バイナリデータの入出力
  3. 1バイトデータの入出力
  4. 複数ファイルのオープン
  5. 全地球の温度上昇トレンド
  6. 今日の宿題

[1] 画像の表現


[2] バイナリデータの入出力

白黒画像は多数の1バイトデータからなります.1バイトのデータ(8個の0と1)をそのまま書き込んだファイルをバイナリファイルと呼びます.今まで扱ってきた,人間が読めるファイルは「テキストファイル」といって区別されます.

今回あつかうデータはバイナリファイルのため,バイナリファイルの読み書きを行う必要があります.次のプログラムは,0.1から1.0までの10個の単精度実数を生成し,それをバイナリ形式でファイル10.datに書き込むプログラムです.

      implicit none
      integer i
      real x
      open(1,file='10.dat',access='direct',form='unformatted',recl=4)

      do i=1,10
         x=0.1*i
         write(1,rec=i) x
      enddo

      end

ここで,form='unformatted'でバイナリ形式を指定し,recl=4で一つのデータ(レコード)の大きさ(今の場合単精度=4バイト=32ビット)を指定します.access='direct'は,直接参照ファイルであることを指定します.今までは'sequential'となっていて,前から順番にファイルにアクセスすることが暗に指定されていました.またwrite文では,rec=iでレコード番号を指定します.このプログラムを実行し,生成された10.datのサイズが40バイトになっていることを確認しましょう.

先ほど生成したデータを読み込んで画面に表示するプログラムは以下になります.

      implicit none
      integer i
      real x
      open(1,file='10.dat',access='direct',form='unformatted',recl=4)

      do i=1,10
       	 read(1,rec=i) x
	 write(6,*) x
      enddo

      end

実行して結果を確認しましょう.


[3] 1バイトデータの入出力

今回扱う画像は白黒256階調なので,各ピクセルは1バイトのデータで表現されます.FORTRANでは符号なし1バイトデータを扱う適当な形式が用意されていないので,character文で宣言される文字型変数に数値を格納します.

第七回に解説しましたが,文字には文字コードと呼ばれる数字が対応しています.そこで,0から255までの整数を文字に一度変換し,その文字をファイルに書き込むと,0から255までの整数(文字コード)がファイルに書き出されます.

0から255までの整数をバイナリデータとしてファイル256.datに書き込み,そのデータを読み出して0から255までの整数を画面に表示するプログラムは以下になります.

      implicit none
      character n
      integer i

      open(1,file='256.dat',form='unformatted',recl=1)

      do i=0,255
         n=char(i)
         write(1,rec=i+1) n
      enddo

      do i=1,256
         read(1,rec=i) n
         write(6,*) i,ichar(n)
      enddo

      end

練習問題1

このデータは,1980年-2000年における全地球の表面気温のデータです.360x180=64800個の4バイトデータ(単精度実数)が並んだファイルが21個あります.それぞれのデータは地球上のある経度(0-359),緯度(0-179)における温度です.注意してほしいのは,二次元的にデータが並んでいるわけではなく,一次元的にデータは並んでいることです.ダウンロードしてunzip data.zipで解凍してください.するとdataディレクトリが生成され,その中にファイルが展開されます.それらのファイルをすべて現在のディレクトリにmv ./data/*.raw ./ コマンドで移動させてください.次に,2,3章で学んだテクニックを用いて

  1. このデータの内ひとつ(例えばtemp1980.raw)を配列(例えばtemp(64800))に読み込み,
  2. 数値を画面に表示させてください.

練習問題2

先ほどのデータを256階調の白黒画像にしましょう.練習問題1のプログラムに引き続き,以下の作業を行ってください.

  1. -15.0度から25.0度までのデータ(temp(64800)に格納ずみ)は0から255までの整数itemp(64800)に変換する.
  2. -15.0度よりも小さいデータは0とする.
  3. 25.0度よりも大きいデータは255とする.
  4. 変換後の0から255までの整数を,バイナリデータとして'temp.raw'というファイル名で保存する.
  5. display -depth 8 -size 360x180 gray:temp.raw を実行し,結果を確認する.

[4] 複数ファイルのオープン

今回は,1980年から2000年までの21年分のデータを解析し,その温度上昇のトレンドが地域ごとにどう分布しているかを調べます.

そのためには,ファイルを21個開かないといけません.正直にプログラムに記述してもいいのですが効率が悪いので,今までに学んだ文字処理のテクニックを用いてファイルを操作します.次のプログラムを実行すると,21個のファイルを順番にオープンしてそのファイル名が画面に表示されます.

      implicit none
      integer i,num,nyear
      character name*12,year*4,bc

      nyear=21

      do i=1,nyear
         num=1979+i
         write(year,'(I4)') num
         name='temp'//year//'.raw'
         write(6,*) name
         open(10+i,file=name,access='direct',form='unformatted',recl=4)
      enddo

      end

write(year,'(I4)') num で,4桁の整数numが文字となって文字型変数yearに格納されます.


[5] 全地球の温度上昇トレンド

さてここまでくると,全地球の温度変化を解析できるようになりました.以下の手順を踏んで,地球上のどこで温暖化がより進行しているのか解析しましょう.

練習問題3

  1. 21個のファイルからそれぞれ64800個のデータを読み込み,配列temp(21,64800)に格納する.
  2. 64800個すべての地点において最小二乗法を用いることにより温度上昇の傾き(℃/年)を算出する.
  3. 2で算出した数値を256階調の整数に変換する.-0.05から0.1(℃/年)までを,0から255までの整数に対応させる.-0.05より小さい値には0,0.1よりも大きい値には255を対応させる.
  4. 64800個の0から255までの整数をcharacter変数を用いることでバイナリファイルtrend.rawに書き込む.
  5. display -depth 8 -size 360x180 gray:trend.raw を実行する.

最後まで実行できたら,以下の点を観察してください.

練習問題4

  1. 低緯度地域と高緯度地域ではどちらが温度上昇率が大きいか?
  2. 海洋と陸域では分布に違いがあるか?
  3. 温度上昇率が特に大きな地域はどこか?

[6] 今日の宿題

プログラムおよび練習問題4の答えを送ること. 〆切は1/26.


日程表へ戻る <<