【Python講座8】Pythonで画像処理

前回まで、PythonとImage Jがどのようにつながっているかを、実際のチュートリアルのコードで見てきました。画像の情報を取得したり、ファイルを表示するような簡単な操作をPythonで行うことが出来ることが分かってきたと思います。

目次

今回は、ピクセル単位で編集を行うような画像解析処理を行います。画像全体の
よりメタな情報(輝度がどれくらいか、平均がどれくらいなのか)を、プログラミング目線から取得する
にはどうすればよいか?を調べています。

Fijiのチュートリアルでは、Iterating Pixelsをご覧下さい。

以下のコードは、前回の最後に紹介しました。これは一体何をするプログラムでしょうか?

これは、画像の中で一番小さな値を示すピクセルがどれにあたるかを調べているプログラムです。
しかし、一つ一つのピクセルを調べていなければ、最小の値は分からないはずです。

従って、前回やってきた統計情報よりもさらに細かな情報を扱うことになります。

Method1~3までが紹介されていますが、具体的にどんなことが書いてあるか、見てみます。

①the for loop, C style(C言語の書き方)…一番簡単な方法です。for文で反復処理させます。
②iterate pixels as a list(ピクセルを全てリストにひとくくりにして反復させる)…iは表示されない。python独自のコードを使って、反復処理で要素を取得する方法。
③apply the built-in min function…reduceという関数を使って最小値を調べる

だいたいこのような感じです!1つずつ見ていきましょう!

①C言語の書き方

以下のような書き方をしています。

このコードでは、minimumをまず最初に設定して、それから順番に画像内のピクセルを一つ一つ調べています。

MAX_VALUE(最大値)をまず最初に代入しておきます。一番最初は一番大きな値を入れておけば、次にどんな
数がきても、最小値が更新されるため、画像の中にある一番小さな値を調べることが出来ます。

ここで、Floatとは、実数に近い浮動小数点までを含めた形式で数値を表す形式です。C言語で扱える実数値は2進数の有限小数で表された数値のため、float型を使うことがあります。もしfloatが原因でエラーが発生した場合、ソフトウェアが浮動小数定数に対応していないことがあります。

今回の場合は、予め、pixel値より極端に大きい値(9999999999とか)を入れておくことで対応出来ます。

len(pixels)…lenはオブジェクトの長さ (要素の数) を返します。今回はピクセル数を返しています。

xrange:()内の情報を取得していて、どこまでの範囲を調べるか指定します。rangeとも似ていますが、for文の中で使われることを想定されます。最近はrange()と書くことが推奨されています。

つまり、画素(pixels)の数だけ、白黒の値を調べていて、小さい値が出てきたらminimumを更新するというコードです。

C言語的な手法の方が、iの要素を取得出来るので、統計解析には使えるが、コードをきちんと書くため、野暮ったいと感じる場合もあるかも知れません。

②ピクセルを全てリストにひとくくりにして反復させる方法

以下のようなコードを書きます。

これはPythonで処理をする時はこういう書き方をします。初心者にとっては見易い書き方ですね。

③reduce(,)を用いて、最小値になるまでピクセルの値を減らしていく。

この書き方は、①や②でやっていることを1行で記述することが出来るのですが、
プログラミングを始めて間もない人は、ちょっととっつきにくいかも知れません。

まずは①や②の書き方で書いてみるのがベストだと思います。

実際に私もやってみました。

まずは、上記のコードをコピー&ペーストして、iterating.pyというファイルを作りました。
次に、Fijiのマクロでこのファイルを開きます。

画像を開いていないと、No Imageと表示されます。そもそも画像が無いと処理が出来ませんよね^^;

今回はレナ画像を利用してみます。画像を開いた状態でRunを押せば、正常に動くはず。。。ところが、、

エラーになってしまいました。先程紹介した通り、floatが原因でエラーが発生した場合、ソフトウェアが浮動小数定数に対応していないことがあります。そこで、float.MAX_VALUEと書かれている箇所を全て999999999などの大きな数字に変えてみました。

試しにこれでRunしてみましょう。すると、、

今度はうまくいきました!Part1~3ともに最小値が35.3333320618と表示されているのが分かると思います。
方法こそ違えど、結果は同じものが返ってきます。

いかがだったでしょうか??ちょっと楽しくなってきませんか?笑

次回は、最小値を画像全体から引き算(Sabtract)する処理を行います!