【画像解析】ImageJをPythonで利用する【Python】

これまでの記事では、ImageJのレコーダー機能を使いマクロで動かす方法を紹介しましたが、ImageJではPythonを利用した解析も行えます。PythonはImageJのマクロより汎用性が高く、マクロよりも複雑なタスクが行えるようになります。

この記事ではImageJ(Fiji)をPythonで操作し、サンプル画像のコロニー数をカウントする処理を紹介します。

動作検証済み環境

Windows 11(22H2), ImageJ 1.54f

ImageJをPythonで利用するには

ImageJとJython(Java上に実装されたPython)の組み合わせにより、画像解析のプログラムをより柔軟に記述することができます。ImageJのスクリプトエディタでは、Pythonを選択してコードを入力し、そのまま実行することができます。さらに、PyImageJというパッケージを使用すれば、Python環境から直接ImageJの機能を利用することも可能です。

Jythonの特徴について

  1. Javaのクラスとのシームレスな統合:
    • Jythonを使用すると、Pythonコード内で直接Javaのライブラリやクラスを呼び出すことができます。これにより、JavaとPythonの両方のエコシステムを活用することができます。
  2. 動的コンパイル:
    • Jythonは動的にJavaのバイトコードにコンパイルされ、Java Virtual Machine (JVM) 上で実行されます。
  3. Python 2.x互換:
    • JythonはPython 2.xシリーズの構文に基づいています。したがって、Python 3.xの機能やライブラリはサポートされていません。

ImageJでJythonを利用する際、Jythonのライブラリが存在しない場合には、自動的にそのライブラリをダウンロードします。一方、Fijiは初めからJythonが組み込まれています。今回は利用のしやすさも加味しFijiでの利用について紹介します。

ImageJでPythonを動かす

今回はImageJではなくImageJの拡張版のFijiを用います。Fijiのインストールの方法はこちらの記事で触れています。

File>New>Text Windowを選択すると以下のようなウィンドウが開きます。

この状態でLanguage>Python(Jython)で言語を切り替えることができます。では、以下を入力して動かしてみましょう。

print('Hello World!')

おなじみのHello Worldを入力し、「Run」もしくはCtrl+R (MacではCommand)を押すと、ウィンドウ下に実行結果が表示されます。

タイル画像を生成させる

次は試しに画像を生成してみましょう。

以下のコードをFijiのテキストウィンドウに入力し実行してみます。

# @ImageJ ij

from ij import IJ, ImagePlus
from ij.process import FloatProcessor
import jarray

def create_checkerboard(width, height, cell_size):
    # セルの数を計算
    n_cells_x = width // cell_size
    n_cells_y = height // cell_size

    # 空の配列を作成
    pixels = jarray.zeros(width * height, 'f')

    # 描画
    for y in range(n_cells_y):
        for x in range(n_cells_x):
            if (x + y) % 2 == 0:
                fill_color = 0  # 黒
            else:
                fill_color = 255  # 白
            
            for dy in range(cell_size):
                for dx in range(cell_size):
                    idx = (y * cell_size + dy) * width + (x * cell_size + dx)
                    pixels[idx] = fill_color

    # FloatProcessor を作成して、ImagePlus に変換
    ip = FloatProcessor(width, height, pixels, None)
    return ImagePlus("Checkerboard", ip)

# 画像を作成
checkerboard = create_checkerboard(200, 200, 20)
checkerboard.show()

実行後、以下のような画像が表示されれば成功です。

このようにPythonを利用してFiji上で画像を生成することも可能です。

コロニー数をカウントする

次に、Fijiで用意されたサンプル画像を使ってコロニー数をカウントします。

画像は以下のようなものです。ここで黒色に表示されたところがコロニーと思われます。この数をPythonを使用してカウントします。

以下のコードをFijiのテキストウィンドウに入力し実行します。

# @ImageJ ij

from ij import IJ
from ij.plugin.filter import ParticleAnalyzer
from ij.measure import ResultsTable

# サンプル画像を開く
image = IJ.openImage("http://imagej.nih.gov/ij/images/Cell_Colony.jpg")
image.show()

# 画像の二値化
IJ.setAutoThreshold(image, "Default dark")
IJ.run(image, "Convert to Mask", "")

# ノイズ除去
IJ.run(image, "Median...", "radius=2")

# 画像の反転
IJ.run(image, "Invert", "")

# 粒子解析(コロニー)をカウント
min_size = 10  # コロニーの最小サイズを指定。
max_size = 1000  # コロニーの最大サイズを指定。
results = ResultsTable()
pa = ParticleAnalyzer(ParticleAnalyzer.SHOW_OUTLINES + ParticleAnalyzer.INCLUDE_HOLES, 0, results, min_size, max_size)
pa.analyze(image)

# 結果の表示
colony_count = results.getCounter()
IJ.log("Number of colonies: " + str(colony_count))

以下のような画像と実行結果が表示されればOKです。

この解析結果では、元画像には192個のコロニーがあると出力されています。どのサイズまでコロニーとして判定させるかによって結果は変わりますが、自動でカウントしてくれるのは大変便利ですね。

コードの解説

1. モジュールのインポート

# @ImageJ ij

from ij import IJ
from ij.plugin.filter import ParticleAnalyzer
from ij.measure import ResultsTable

@ImageJ ij は、ImageJのインスタンスを注入するためのマジックコマンドです。これにより、スクリプト内でImageJのAPIにアクセスできるようになります。次に、ImageJの主要なクラスや関数をインポートしています。

2. サンプル画像の読み込み

image = IJ.openImage("http://imagej.nih.gov/ij/images/Cell_Colony.jpg")
image.show()

ImageJの公式サイトから “Cell_Colony.jpg” というサンプル画像を読み込み、その画像を表示しています。

3. 画像の二値化

IJ.setAutoThreshold(image, "Default dark")
IJ.run(image, "Convert to Mask", "")

画像を二値化しています。具体的には、暗い部分を強調するデフォルトのしきい値を適用し、その結果をもとに画像をマスク化(二値化)しています。

4. ノイズの除去

IJ.run(image, "Median...", "radius=2")

メディアンフィルタを適用してノイズを除去しています。このフィルタは、各ピクセルの周囲の値を考慮して、その中央値を新しいピクセルの値として設定します。

5. 画像の反転

IJ.run(image, "Invert", "")

白と黒のピクセルを反転しています。この後のParticleAnalyzerによる解析処理では、デフォルトで白い領域をカウントするため反転させます。

6. 粒子解析

min_size = 10
max_size = 1000
results = ResultsTable()
pa = ParticleAnalyzer(ParticleAnalyzer.SHOW_OUTLINES + ParticleAnalyzer.INCLUDE_HOLES, 0, results, min_size, max_size)
pa.analyze(image)

ParticleAnalyzerを使用して、指定されたサイズ範囲内のオブジェクト(ここではコロニー)をカウントしています。この解析では、オブジェクトの輪郭を表示し、内部に穴があるオブジェクトも含めて解析を行います。

今回は、10ピクセル以上、1000ピクセル未満を一つのコロニーとしてカウントしました。

6. 結果の表示

colony_count = results.getCounter()
IJ.log("Number of colonies: " + str(colony_count))

解析の結果得られたコロニーの数をカウントし、Fijiのログウィンドウに表示します。

最後に

今回はImageJ(Fiji)を利用して、Pythonでの簡単な画像解析について紹介しました。

PythonはImageJのマクロよりも汎用性が高く、すでにある程度Pythonが使える方は簡単にImageJの操作を行うことができます。

ぜひ、Pythonを利用したImageJの画像解析を試していただければと思います。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です