ImageJを使った体積測定

共焦点顕微鏡が普及している現在、簡単にできそうな体積の測定ですが、意外に手こずることがあります。 「面積は簡単だったから体積だって!」という方、読んでみてください。

目次

簡単にできる(はずの)体積測定

共焦点顕微鏡やCTなどのデータは画像を重ね合わせたスタックとして扱うことで3次元的なデータを表現します。 当然、体積の測定もできるはずで、ImageJを使えば簡単にできる、と思いきや、つまずいた方はいませんか? 原理的には単純で簡単にできる体積測定ですが、実際に行う際のコツや気をつける点をまとめてみます。

デモデータ

今回はデモ用に蛍光ビーズのzスタック画像を用意しました。ここからダウンロードできます。

蛍光ビーズ画像

データをImageJで読み込み、表示すると真っ暗で何も見えなかったりするかもしれませんが、[Image -> Adjust -> Brightness/Contrast...] とクリックしてコントラストを調整するパネルを表示し、調整することでくっきりと8つの蛍光ビーズが見えるはずです。さらに、 背景ノイズを確認するために弱いシグナルを可視化するようにコントラストを調整すると、以下の写真のようにバックグラウンドノイズが乗っている いることが分かります。

背景のノイズを強調した画像

解析操作

計測時には測定対象を決めるためのセグメンテーションをしますが、セグメンテーションの際にはノイズが邪魔になります。 データ表示で確認したバックグランドノイズを取り除くために、解析前に簡単な画像処理をしましょう。 ノイズを取り除くためには様々な処理がありますが、今回はメディアンフィルタを使います。メディアンフィルタは 細かなノイズを取り除くとともにもともとの構造(輪郭)を比較的保存することが知られており、今回のような処理にはうってつけです。 [Process -> Filters -> Median...] とクリックするとパネルが出てくるので、フィルタの大きさを決めてOKボタンを押します。 今回はradiusを2.0にしました。

メディアンフィルタをかけた画像

フィルタをかけた後、測定を行います。体積を測れるImageJのプラグインはいくつかありますが、 Fijiのメニュー[Analyze]に組み込まれている3D Object Counterを使ってみます。 このプラグインはフランス国立科学研究所のFabrice Cordelièresによって作成されています。 蛍光ビーズのデータファイルを開いたまま、[Analyze -> 3D Object Counter]をクリックすると以下のパネルが出ます。

ObjectCounterパネル

パネルではデータをみながら測定対象とするセグメントを定義する閾値を決めます。 一つの画像で閾値を決めても別のSlice(別の深さの画像)で適切かどうかは保証できません。 全てのSliceで意図に合った閾値となる値を探してください。そのような値がない場合は、 計測の前にフィルタなどの画像処理を施す必要があります。 パネル内の"Size filter:"のパラメータは測定対象とする範囲を定め、対象外は測定結果に含めません。単位はvoxelです。 "Exclude objects on edges"のチェックは画像の縁に触れるもの(画面からはみ出しているもの)を測定結果から除外するかどうかを決めます。 "Maps to show:"以後のチェックは下に示す測定結果を表示するかどうかで、以下の解析結果の説明で示します。

解析結果

パラメータを設定してOKボタンを押すと、しばらく計算時間がとられ(何も表示がないので不安になりますが、待てば結果が出るはずです!) なにやらウィンドウがいくつか出現します。以下、簡単に解説をします。

objects mapの画像

測定対象となったピクセルを表示します。そのままだとほぼ真っ黒で、表示されたピクセルがみえないので、[LUT > Glasbey inverted ]としてLUTを変更してください。個々のビーズが異なる色で表示され、視認できるようになります。GlasbeyというLUTは、階調全体に渡ってなるべくランダムに色が配分されるように考慮されたLUTで、このようなラベリングを目的とする画像(Categorical image:名義画像といいます)に対して用いることを目的として設計されています 。このLUTは白を背景とする画像になりますが、生物画像用には黒の背景を用いることが多いので、Fijiには組み込まれているGlasbey Invertedという背景が黒の独自のLUTを使いました(Cf. #1)。ビーズに添えられた数字はビーズそれぞれのID番号で、Resultsの表に表示される行番号の数値結果に対応します。ビーズのそれぞれのピクセル値を確認すると、これらのID番号が対応していることがわかるかと思います。これらは全て、二値化の閾値とサイズフィルタにひっかかったピクセルになります。

surface mapの画像

surface_mapは計測対象の表面を示したものです。先ほどとおなじようにLUTを変更してみてください。中抜きの円を見ることができるはずです。複雑な形状の測定対象の場合、このような表示も理解の一助になると思います。

centres of massesの画像

center of massは日本語で重心になりますが、各voxelの輝度値で重み付けしたxyz座標平均です。 測定対象の数がラベルされ、その位置がデータとして得られます。蛍光ビーズのデータはそれぞれの位置が ほぼ同じ焦点面にあったので、同じsliceにcenter of massが集まっています。

centroidsの画像

centroidも重心ですが、こちらは輝度値で重み付けをしていません。測定対象の輝度値が一様であればcenter of massとcentroidは等しくなるはずです。
これらの画像と同時に表も出現し、実際に測定された数値が得られます。 表中、一番左端の数字は上記に示した測定対象のラベルを示しますが、その横に今回の解析目的である体積の測定値が表示されています。 今回はほぼ同じ大きさの蛍光ビーズだったのでほぼ同じ値が得られています。

出力されるresultsの表1

(横に長いので半分表示しています)

出力されるresultsの表2

(横に長いので半分表示しています)

正確な体積測定のために

さて、基本的には2,3のクリックだけでスタックデータに含まれる3次元中の多数の計測対象について、体積が測定できました。大事なポイントをおさらい、考察します。

また今回は便利なのでプラグインを使いましたが、もちろんマクロやスクリプトを作成することで面積測定から体積を算出することも可能です。

測定値の検証と3次元計測の勘所

さて、今回計測したビーズは半径4マイクロメートルの規格のものを使いました。ビーズは球形をしているはずですが、[Image -> Stacks -> Orthogonal Views]を使ってデータを見るとz方向に伸びて見えます。計測値と実際の値の差を考える上で、3次元データもしくは共焦点画像データ特有の問題について次回触れたいと思います。お楽しみに。