画像間の演算
みなさんよくご存じの植生指標(例えば、NDVI)は、デジタル値が格納された衛星データの複数のバンドのデータの演算によって計算することができます。では、どのようなプログラムを書いたらよいでしょうか。
NDVI(Normalized Difference Vegetation Index)は赤と近赤外のバンドの値の正規化された比で、NDVI=(NIR-Red)/(NIR+Red)で計算できます。ここで、NIRは近赤外、Redは赤のバンドの値で、デジタル値そのまま使うこともありますし、反射率に変換してから計算することもあります。
ここで、注意しなければいけないことは、衛星データが8ビット整数、あるいは16ビット整数で格納されている場合でも、演算結果は実数になるということです。また、8ビット、16ビット整数は符号なしと符号付きの二つの型があり、Cプログラムではきちんと型宣言を行う必要があります。整数には32ビットもありますが、それぞれの値域は下記の通りです。
符号なし8ビット整数:(unsigned char): 1〜255
符号付き16ビット整数(signed short):-32768〜32767
符号なし16ビット整数(unsigned short):0〜65535
符号付き32ビット整数(signed int): -2147483648〜2147483647
符号なし32ビット整数(unsigned int):0〜4294967295
整数でも、演算結果は実数になりますが、実数には4バイト(32ビット)と8バイト(64ビット)の二種類があります。
4バイト実数(float)
8バイト実数(double)
変数には値域があり、演算結果によってはオーバーフローしてしまうことがあり、バグの原因になりますので、注意しましょう。
演算は下記のように、"="を使って行います。Cプログラムでは最後に;を付けることをお忘れなく。
a=b*c;
この場合、a,b,cが8ビット整数で、b,cがそれぞれ1,2の場合、計算結果の3がaに代入されます。しかし、b,cが例えば、20,30の場合、計算結果は600ですので、8ビット整数の上限、255を超えてしまい、エラーになってしまいます。
エラーを回避するには、aを例えば、short(符号付き16ビット整数、signedは省略可)で宣言しておけば、正しい計算結果がaに格納されます。変数の型変換は代入の際に、自動的に行われますが、プログラム作成過程でバグを避けるために、a=(short)(b*c);と書くこともあります。(short)で型変換を明示します。こう書いておくと、バグ取りをする際に、ここは大丈夫ということになり、安心しますね。
では、ランドサットTMデータから、NDVIを計算し、実数として出力するプログラムを紹介しましょう。TMデータは符号なし8ビット整数で格納されていますから、unsigned charで宣言した変数にデータを読み込み、floatの変数に出力することになります。
ここから、プログラムをダウンロードしましょう。
演習:プログラムを改良し、BILあるいはBSQ形式で格納されているデータを入力できるようにしましょう。