Re - ImageJで学ぶ!: 2015-09-06

2015年9月12日土曜日

第13回 画像処理フィルタ入門(その2)で学ぶ!

前回は画像処理フィルタについてやさしい入門を解説しました。
今回はImageJを用いた画像の濃淡値を操作する空間フィルタリングの技の一部を解説します。
画像をフィルタリングすることの長所・短所を知り、その長所を生かすことができる人は画像を解釈する上で合理的判断ができる人だと思われます。

空間フィルタリングの考え方


前回の「画像処理フィルタ入門」では、コンボリュージョンカーネルという3×3、5×5画素近傍のテンプレートと元画像をコンボリューション(重責積分)することによって空間フィルタリング処理が実施されるという説明をしましたが、今回はもう少し踏み込んでフィルタリングに関する分類を含めて整理します。

画像処理には、濃淡情報に関するデータ変換処理(強度変換)とピクセル配列に対する座標変換処理(空間座標変換)があり、空間フィルタリングは名称のとおり、空間座標変換の1つです。

厳密には、例えば、平均化フィルタなどは画像局所の濃淡値の平均値を再配列する処理でもあり、フィルタリングは強度変換と空間座標変換の両方が相補的に作用します。

ImageJによるフィルタ処理プログラムの書き方


ImageJを本格的に使いたいユーザは、Java言語を用いたプラグインプログラムを勉強するといいでしょう。このとき、1から作ろうとせず、すでに公開されているプラグインの中から、自分がやりたい処理に似ているものを探して、ライセンス条項に違反せずに、改変して勉強させてもらうといいと思います。

ImageJ既存の機能で空間フィルタリングする場合、ImageJのメニューからProcess>Filtersを選択して利用できます。

利用できるフィルタは次のようなものがあります。

(ImageJ日本語情報SeesaaWikiより引用)

いろいろなフィルタがありますが、今回は不均等な濃淡の変化がある画像を均一にするHarris氏が1977年に提唱したCVE(constant variance enhancement)処理を例に見ていきましょう。
このCVE処理は、ImageJを使って、次のような流れで画像を処理していきます。
  1. 元画像を準備します。(ImageJに表示します。)
  2. 局所平均化をした画像を作ります。(ImageJメニューのProcess>Filter>mean...で任意のピクセルを入力し、局所平均の大きさを決めます。)
  3. 元画像からこの局所平均画像を引きます。(Process>Image Calculator...で起動した後、一段目の画像に元画像、2段目の画像に局所平均画像、計算方式は"Sbtract")必要に応じて、Process>Math>Absで、画素値を絶対値にしてください。
  4. この差分画像の局所分散化した画像を作ります。(同じく、Variance...を選択して処理します。このとき、分散の幅は小さくしましょう。)
  5. 差分画像から分散画像を割ります。(Process>Image Calculator...で起動した後、一段目の画像に分子となる画像、2段目の画像に分母となる画像、計算方式は"Divide")

いろいろ試したみたのですが、設定値の甘さで、筆者の例ではあまりうまくいかなかったので、参考記事の画像を引用させていただきます。
(もしうまく行ったという事例などありましたら、コメントくださいm(__)m)

(参考記事より引用)

濃淡の差で見えずらくなっていた領域が一目で見れるようになっていることがわかります。もちろん、元画像のコントラストを調整しても見ることができるようになると思いますが、俯瞰的に見る必要があるときには有用な手段ですね。

一点、注意点として、コントラストを均一化する処理にヒストグラムイコライゼーションというものがありますが、この処理は画像の再マップを行うことなく強度のみを最適化しているので、フィルタリングの操作ではなく、ヒストグラムを確率密度関数として、情報エントロピーを最大にする処理です。

今回は画像処理フィルタの中でも特に局所統計量を再マップする画像変換、および強調処理の説明を行いました。

次回も空間フィルタリングについての話を進めます!

Reference
  • 山本修司:ImageJで学ぶ実践医用・バイオ画像処理.INNERVISION(20・13) 2005, p80-82

2015年9月10日木曜日

第12回 画像処理フィルタ入門で学ぶ!

今回は、画質を改善することを目的として、画像処理フィルタを使っていきます。
一般的に、画像には物理的なノイズや歪みが含まれていますが、このような、なんらかの画質劣化を目立たないようにして、見たい部分を見やすくしたり、画像に含まれる特定の情報だけを抽出したりすることが画像処理フィルタの役割です。

ImageJでは多くの画像処理フィルタが用意されていますが、今回はまずはやさしく、その使い方を探っていきます!

コンピュータ内部での画像の扱いと画素の表記

取り扱うものは画像なので、実際には画像を構成する最小単位である「画素(ピクセル)」を取り扱っていきますが、この画素が画像として表現されるための格納方式というものがあります。これを理解すると、画像フィルタの理解が容易になるので先に説明します。

平面のデジタル画像は画素が二次元配列されたものです。例えば、次のようなMRI画像でも、左上をすごく拡大してみると、角ばったものが見えます。これが画素です。




これを演算として表現すると、次のように表されます。


この一番左上から画素をf(0,0)と表現するのが通例です。
画像のフォーマットとして基礎的なビットマップフォーマットでは、この一番上の行の左側から順に、左から右へ一行走査しては一段ずつ下にいく順次格納の方法がとられます。
カラー画像の場合は、RGBの各プレーンの3面の合成によって1つの画像として表されるために、この走査が”R””G””B”の3層繰り返されます。
この繰り返しの時には次の3つの格納方式があります。
  • RGBのそれぞれの面をグレースケール画像と同じ形式で格納する「面順次格納方式」
  • 各RGBプレーンの1ラインごとを格納していく「線順次格納方式」
  • 1画素ごとにRGBそれぞれの値を格納していく「点順次格納方式」

画像処理フィルタを使った画像の演算後の格納方式は、フィルタをかける前の元データの格納方式に準ずる場合が通例で、元画像がカラー画像の場合には、フィルタをかける前に元データの格納方式を知っておくとより深く理解できると思います。

空間フィルタリング

前述した画像の、ある一つの画素を中心として、その周辺の画素群(局所領域)を用いて計算した結果を出力画素値として置き換える処理のことを「空間フィルタリング」といいます。
このときに用いるフィルタを「空間フィルタ」といいます。
空間フィルタは線形フィルタと非線形フィルタに大別され、線形フィルタのフィルタリングでは、入力画像をf(i,j)、出力画像をg(i,j)とするとき、次式によって計算させます。



h(m,n)はフィルタ係数を表す配列であり、(2W+1)×(2W+1)のマトリックスです。このマトリックスが空間フィルタそのもので、「加重マトリックス」や「重み係数行列」などとも呼ばれています。
局所マトリックス内の処理だけを指すときは近傍処理といい、W=1のときは3×3、2のときは5×5画素近傍を用いた近傍処理といいます。

では、実際に空間フィルタ(線形フィルタ)を使ってどのようにフィルタリングするのかを3×3画素近傍処理を例に説明します。

やり方はいたって簡単です。
まず、ImageJでオリジナル画像(前述の膝の画像:グレースケール)を読み込み、メニューからProcess>Filters>Convolve…を選択し、Convolverを起動してから、値を記述します。(ImageJでは空間フィルタをカーネルと呼びます。)
カーネルの内容を記述するとき、初期設定では5×5の加重フィルタが記録されていますので、3×3に変更します。4行目の改行などがあると怒られるので注意してください。
設定後、次のような状態になるはずです。



そしてこれを「OK」で実行し、コントラストをみやすく調整すると、次のような画像が得られます。

画像が硬い感じがしますね。先のカーネルでは、対象となるピクセル値を強調するものでしたのでこのようなメリハリの効いた画像が得られます(一方で、ノイズは増えます)。
このような処理が、空間フィルタリングです。

では実際にはどのように各画素が計算されているのかをみていきましょう。
ImageJでは、各画素の濃淡値をテキストデータで出力できますので、処理前の画素値データと処理後の画素値データを見比べていきましょう。
それぞれのテキストデータを出力後、全て選択してからエクセルに貼り付け、それぞれのエクセルデータを作成してみました。
次の図は、オリジナル画像の全画素値(512×512)を行列で並べ、その左上を表示したものです。

(オリジナル画像左上の画素値)

(フィルタリング画像左上の画素値)

どのように計算されているのかを知るには、任意の1ピクセルの計算方法を知るだけで理解できます。あとは、それが全ピクセルで繰り返されているだけの話です。

ここでは、オリジナル画像の任意のピクセル(エクセル図中のオレンジに囲まれた黄色セル)とその外周のオレンジのピクセル(全9ピクセル)を例にその処理方法を見ていきます。

この任意のピクセルの濃淡値を算出する場合、フィルタ係数とオリジナル画像の画素値の積和演算を行っていきますので、今回の加重フィルタの場合、次のように計算されます。

46×(-1)+45×(-1)+40×(-1)
320×(-1)+208×(9)+189×(-1)
339×(-1)+271×(-1)+175×(-1)
=447

空間フィルタリングでは、この計算で算出される値がこの局所マトリックスの中心として置きかわりますので、この例では、208(オリジナル)が447(処理後)になっていることがわかります。
この処理がすべてのピクセルに行われ、濃淡値が置き換えられると、フィルタ処理結果画像が得られます。

一点、注意点があります。
局所フィルタは一般的に3×3や5×5などを用いることが多いですが、この場合、3×3の場合は最外周、5×5の場合は最外周とその内側の1行列は、外側の画素がないので、正しい画素近傍計算ができません。対策としては強制的に出力画素値を0にしてしまうなど、適当な値を埋めて、画像の解釈に影響しないように留意しましょう。

これでカーネルの入門の入門はおしまいです。
臨床では、検査技師さんが、CTやMRIなどの画像処理をするときに、この操作をしてくれていて、みやすい画像を作ってくれているんですよ~。

次回もフィルタについて説明していきます!

(知っ得)
今回はサンプル画像にMRI/T2w image-ACL level を使用しています。この画像はOsiriX sample画像のKneeに含まれています。
OsiriXのサンプル画像はほとんどが圧縮されたDICOM画像です。デフォルト設定のImageJは非圧縮DICOMのみ読み込むことができますので、そのままでは読み込むことができません。

この対策として、一旦、OsiriXでサンプルデータを読み込んでから、書き出しをしましょう。この書き出しの操作のときに、次の図のように、圧縮の項目内の「すべてのDICOMファイルを解凍」を選択しておきます。


これで、ImageJでもDICOMファイルを読み込むことができます。

Reference
  • 山本修司:ImageJで学ぶ実践医用・バイオ画像処理.INNERVISION(20・12) 2005, p100-101