科学的研究や工業分野で、精密な画像解析が必要とされる場面は多々あります。ImageJはそのようなニーズに応える、非常に便利なツールです。特に形状分類や検出は、生物学の細胞計測から材料科学の粒子分析まで、幅広い応用があります。
これまで、ImageJおよびFijiを利用した画像内の粒子数計測や形状分類を行ってきました。今回は画像内のスケールを利用してサイズ計測を行う方法について紹介します。
Fiji(1.54f), ImageJ 1.54f, Windows11(22H2)
スケールの設定
次の画像のように画像内にスケールバーがあるものは、次に紹介する操作で画像内のピクセルと対応させることができます。
まず、File>Open Samples>Embryos
で同じ画像を開きます。次にツールバーのStraight
を選択します。
embryos.jpgの画像が開ければ、画像右下のスケールに沿うように線を伸ばします。
Analyze>Set Scale…
を選択すると、以下のようなウィンドウが開くので、各パラメータを設定していきます。
- Distance in Pixels: 画像上で測定した距離(ピクセル単位)を入力します。ここで設定する数値によって、その長さが画像内の何ピクセルに相当するかが決まります。先ほど直線ツールでスケールの上に重ねた直線の長さがあらかじめ入力されていると思います。今回の例では470ピクセルあたりになっているかと思います。
- Known Distance:
Distance in Pixels
で指定した距離に相当する実際の距離を入力します。つまり、画像内のスケールに相当します。今回の画像では100 µmになるため、100を入力します。 - Pixel Aspect Ratio: 画像のピクセルが持つ縦横比のことを入力します。今回は1:1の正方形のピクセルと考え、1.0のままにしておきます。
- Unit of Length: スケールの実際の単位を指定します。今回のスケールは100 µmなので、µmを入力します。
- Global: このオプションをチェックすると、現在の画像に設定したスケールが、今後開くすべての画像に適用されます。
ここまで設定すれば、この後の操作で1 µmあたり4.7 ピクセルとして解析することができます。
Fijiによるサイズ計測の方法
これまでの設定で画像内スケールを手動で設定しました。この操作ももちろんマクロやPythonで実行することができます。
今回はPython (Jython)を利用し、スケールの設定から画像内の長さを測定してみます。
Fijiを起動後File>New>Text Window
を選択し、Language>Python(Jython)
で言語をPythonに設定します。
テキストウィンドウに以下のコードを入力し、左下のRun
をクリックし実行してみます。
# @ImageJ ij
from ij import IJ
from ij.measure import ResultsTable
from ij.plugin.filter import ParticleAnalyzer
image = IJ.openImage("http://imagej.nih.gov/ij/images/embryos.jpg")
image.show()
# 画像を8-bit グレースケールに変換して二値化
IJ.run(image, "8-bit", "")
IJ.run(image, "Gaussian Blur...", "sigma=2") # ノイズの除去
IJ.run(image, "Auto Threshold", "method=Otsu white")
IJ.run(image, "Set Scale...", "distance=470 known=100 unit=µm")
IJ.run(image, "Convert to Mask", "")
# オブジェクトの検出とカウント
table = ResultsTable()
pa = ParticleAnalyzer(ParticleAnalyzer.SHOW_RESULTS, ParticleAnalyzer.AREA + ParticleAnalyzer.FERET, table, 0, float('inf'), 0.0, 1.0)
pa.analyze(image)
# 検出されたオブジェクトの数
print("Number of objects detected: " + str(table.getCounter()))
# オブジェクトの特性の計測
for i in range(table.getCounter()):
# 例として、オブジェクトの最大径(フェレ径)を取得
feret = table.getValue("Feret", i)
print("objects " + str(i+1) + " Max diameter: " + str(feret) + " um")
実行結果
以下のような2つのウィンドウが表示されれば成功です。
今回はImageJおよびFijiを利用したスケールバーを利用したサイズ計測を行う方法を紹介しました。この方法で画像内のオブジェクトを現実の長さでとらえることができます。
テーブルを確認します。例えば一つ目のオブジェクトのFeretが15.153となっていますが、これは15.153 µmの長さが計測されたことを意味します。
この結果をcsvファイルなどで出力すれば、エクセルやその他ソフトで解析にまわすことも可能です。今回出力した各パラメータは以下の通りです。
- Area:画像内オブジェクトの面積。
- Feret:フェレ径。画像内オブジェクトの2点間の最長距離(最大径)。
- FeretX(およびFeretY):フェレ径を定義する直線のXおよびY座標。
- FeretAngle:画像の水平軸に対するフェレ径の角度。
- MinFeret:画像内オブジェクトの2点間を結ぶ直線の最短距離。
コードの解説
1. モジュールのインポート
# @ImageJ ij
from ij import IJ
from ij.measure import ResultsTable
from ij.plugin.filter import ParticleAnalyzer
from ij import IJ
:ImageJライブラリからIJクラスをインポートします。IJクラスはImageJの機能へのアクセスを提供します。from ij.measure import ResultsTable
:測定結果を格納するためのクラスをインポートします。from ij.plugin.filter import ParticleAnalyzer
:粒子分析用のクラスをインポートします。
2. 画像の読み込みと表示
# サンプル画像を開く
image = IJ.openImage("<http://imagej.nih.gov/ij/images/embryos.jpg>")
image.show()
IJ.openImage(url)
:指定されたURLから画像を読み込みます。image.show()
:画像を表示します。
3. 画像の前処理
# 画像を8-bit グレースケールに変換して二値化
IJ.run(image, "8-bit", "")
IJ.run(image, "Gaussian Blur...", "sigma=2") # ノイズの除去
IJ.run(image, "Auto Threshold", "method=Otsu white")
IJ.run(image, "Set Scale...", "distance=470 known=100 unit=µm")
IJ.run(image, "Convert to Mask", "")
IJ.run(image, "8-bit", "")
:画像を8ビットのグレースケールに変換します。IJ.run(image, "Gaussian Blur...", "sigma=2")
:ガウシアンブラーを適用して画像のノイズを減少させます。**sigma=2
**はブラーの強度を指定します。IJ.run(image, "Auto Threshold", "method=Otsu white")
:自動しきい値処理を使用して画像を二値化します。Otsuの方法は、画像のヒストグラムを基に最適なしきい値を見つけ出し、それを用いて画像を二値化します。IJ.run(image, "Set Scale...", "distance=470 known=100 unit=µm")
:画像のスケールを設定します。先ほど手動で行ったSet Scale
のパラメータが相当します。IJ.run(image, "Convert to Mask", "")
:後続のオブジェクト検出のため一度画像の色を反転します。
4. オブジェクトの分析
# オブジェクトの検出とカウント
table = ResultsTable()
pa = ParticleAnalyzer(ParticleAnalyzer.SHOW_RESULTS, ParticleAnalyzer.AREA + ParticleAnalyzer.FERET, table, 0, float('inf'), 0.0, 1.0)
pa.analyze(image)
table = ResultsTable()
:ResultsTable
の新しいインスタンスを作成します。これは、検出された各オブジェクトの解析結果(面積、最大径など)を格納するためのテーブルです。pa = ParticleAnalyzer(...)
:ParticleAnalyzer
の新しいインスタンスを作成し、その挙動を設定します。このインスタンスは、画像内のオブジェクトを検出し、測定します。 各引数の詳細は下記のとおりです。ParticleAnalyzer.SHOW_RESULTS
:解析後に結果を表示するかどうかを指定します。このフラグがセットされていると、測定結果が新しいウィンドウでユーザーに表示されます。ParticleAnalyzer.AREA + ParticleAnalyzer.FERET
:解析する際に計測するパラメータを指定します。ここではオブジェクトの面積とフェレ径が計測されます。table
:解析結果を保存するResultsTable
のインスタンスを指定します。0
:解析するオブジェクトの最小サイズ(面積)を指定します。今回は0
としているため、サイズに基づくフィルタリングは行いません。float('inf')
:解析するオブジェクトの最大サイズ(面積)を指定します。float('inf')
は無限大を意味するため、今回の設定ではフィルタリングを行っていません。0.0, 1.0
:これらの値は、オブジェクトの円形度(circularity)の範囲を指定します。0.0
から1.0
までの値で、1.0
は完全な円を意味します。ここでは全範囲が指定されているため、円形度に基づくフィルタリングは行いません。
pa.analyze(image)
:解析を実行します。
5. 結果の表示
# 検出されたオブジェクトの数
print("Number of objects detected: " + str(table.getCounter()))
# オブジェクトの特性の計測
for i in range(table.getCounter()):
# 例として、オブジェクトの最大径(フェレ径)を取得
feret = table.getValue("Feret", i)
print("objects " + str(i+1) + " Max diameter: " + str(feret) + " um")
フェレ径の解析結果をテキストウィンドウに出力しています。以下のように出力されていれば問題ないです。
最後に
今回はImageJおよびFijiを利用したスケールバーを利用したサイズ計測を行う方法を紹介しました。この方法で画像内のオブジェクトを現実の長さでとらえることができます。
ぜひ、Fijiを利用して画像解析を試していただければと思います。