mcpField
P
pyimagej-fiji-bridge

pyimagej-fiji-bridge

github.com/jaechang-hitsデータ・データベース38477 回インストール1 週間前に更新
リポジトリ

pyimagej-fiji-bridge について

PyImageJは、PythonからImageJ2やFijiを呼び出すためのブリッジスキルです。Pythonの画像処理とFijiプラグイン、マクロ、測定を組み合わせたい研究者向けで、ヘッドレス処理とNumPy・ImageJ間のデータ変換に対応します。

主な機能

  1. 01PythonからFijiプラグインを呼び出し
  2. 02ImageJマクロファイルの実行
  3. 03ヘッドレスでのバッチ処理
  4. 04NumPyとImageJ画像の変換
  5. 05ImageJ Opsによる画像処理
  6. 06測定結果をDataFrameとして取得

活用シーン

  1. 01既存のFijiマクロを一括実行
  2. 02Bio-Formatsで顕微鏡画像を読み込み
  3. 03TrackMateで粒子を追跡
  4. 04ImageJの測定結果を統計解析に利用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill pyimagej-fiji-bridge

インストール後、Claude Code で/pyimagej-fiji-bridgeを入力して読み込まれたか確認します。

詳細

PyImageJ — ImageJ/Fiji への Python ブリッジ

概要

PyImageJ は、PyJNIus と scyjava を通じて ImageJ2 および Fiji の Python インターフェースを提供し、Python プロセス内に完全な Java 仮想マシンを組み込みます。NumPy 配列と ImageJ の ImagePlus/ImgLib2 データ構造の間で双方向のデータ交換が可能なため、Python で画像の前処理を行って Fiji プラグイン(Bio-Formats、TrackMate、Analyze Particles、Weka segmentation)に渡し、結果を pandas DataFrame に戻せます。スクリプトやバッチ処理向けのヘッドレス動作に加え、Fiji の対話的なセッション向けの GUI モードにも対応しています。

使用する場面

  • Python から Fiji 専用のプラグインを実行する場合:Bio-Formats による複数形式の I/O、TrackMate による粒子追跡、CLIJ2 による GPU 処理、コミュニティの Fiji アップデートサイトのプラグイン
  • Fiji GUI を開かずに ImageJ マクロのパイプラインをヘッドレスで自動化する場合(例:実験全体の一晩かけたバッチ処理)
  • ImageJ の型システムをフル活用して、ImageJ Ops フレームワーク(150 以上の画像処理操作)を適用する場合
  • 往復処理のために、NumPy 配列(SciPy エコシステム)と ImageJ のハイパースタック(TZCYX のチャンネル順)を相互変換する場合
  • ImageJ Results テーブルと ROI Manager の測定結果を解析し、後続の統計分析用に pandas DataFrame にする場合
  • 既存の .ijm マクロファイルを書き換えずに Python ワークフローの一部として実行する場合
  • Fiji プラグインを使わない純粋な Python 処理が必要な場合は、代わりに scikit-image を使用してください。scikit-image はインストールが速く、JVM のオーバーヘッドもありません
  • 対話的な多次元画像の可視化や注釈には、代わりに napari を使用してください。PyImageJ はビューアーの代わりにはなりません

前提条件

  • Python パッケージ:pyimagej、scyjava、numpy、pandas
  • Java:Java 8 または Java 11(Java 17 はサポートされていません)。Java を確実に管理するには conda を使用してください
  • Fiji/ImageJ2:初回の初期化時に自動でダウンロードされます。または、ローカルの Fiji インストールパスを指定してください
  • 環境:conda 環境を強く推奨します。pip のみでインストールすると、JVM のパスに関する問題が起きることがよくあります
# Recommended: conda installation
conda create -n pyimagej -c conda-forge pyimagej openjdk=11
conda activate pyimagej

# Install additional dependencies
pip install pandas tifffile

# Verify
python -c "import imagej; ij = imagej.init('sc.fiji:fiji', mode='headless'); print(ij.getVersion())"

クイックスタート

import imagej
import numpy as np

# Initialize Fiji in headless mode (downloads on first run, ~500 MB)
ij = imagej.init("sc.fiji:fiji", mode="headless")
print(f"ImageJ version: {ij.getVersion()}")

# Create a test image, process with Gaussian blur via Ops, convert back
arr = np.random.randint(0, 1000, (256, 256), dtype=np.uint16)
imp = ij.py.to_imageplus(arr)
blurred = ij.op().filter().gauss(imp.getProcessor(), 2.0)
result = ij.py.from_imageplus(imp)
print(f"Processed array shape: {result.shape}, dtype: {result.dtype}")

コア API

モジュール 1:初期化

PyImageJ は、Python のセッションごとに一度初期化する必要があります。mode とエンドポイントによって、使用する ImageJ ディストリビューションと GUI の動作が決まります。

import imagej

# Headless Fiji — most common for scripts and batch jobs
ij = imagej.init("sc.fiji:fiji", mode="headless")

# GUI mode — opens the Fiji window (requires a display)
ij = imagej.init("sc.fiji:fiji", mode="gui")

# Local Fiji installation — faster startup, no download
ij = imagej.init("/path/to/Fiji.app", mode="headless")

# Specific Fiji version
ij = imagej.init("sc.fiji:fiji:2.14.0", mode="headless")

# Bare ImageJ2 without Fiji plugins
ij = imagej.init("net.imagej:imagej", mode="headless")

print(f"ImageJ version: {ij.getVersion()}")
print(f"Headless: {ij.ui().isHeadless()}")
モジュール 2:画像 I/O

ImageJ の I/O レイヤー(独自形式に対応する Bio-Formats を含む)を使用して画像を開いて保存し、ImageJ と NumPy の表現を相互変換します。

import imagej
import numpy as np

ij = imagej.init("sc.fiji:fiji", mode="headless")

# Open any format Bio-Formats supports: CZI, LIF, ND2, ICS, TIFF, etc.
imp = ij.io().open("/data/experiment.czi")
print(f"Dimensions: {imp.getDimensions()}")   # [W, H, C, Z, T]
print(f"nSlices: {imp.getNSlices()}, nFrames: {imp.getNFrames()}")

# Save image
ij.io().save(imp, "/data/output.tif")
print("Saved output.tif")
# NumPy ↔ ImageJ conversion
arr = np.zeros((100, 100), dtype=np.uint16)
arr[30:70, 30:70] = 1000   # bright square

# NumPy → ImagePlus
imp = ij.py.to_imageplus(arr)
print(f"ImagePlus: {imp.getWidth()}×{imp.getHeight()}, type={imp.getType()}")

# ImagePlus → NumPy (returns a view where possible)
arr_back = ij.py.from_imageplus(imp)
print(f"NumPy array: shape={arr_back.shape}, dtype={arr_back.dtype}")

# Multi-channel array: shape (C, H, W)
rgb = np.random.randint(0, 255, (3, 256, 256), dtype=np.uint8)
imp_rgb = ij.py.to_imageplus(rgb)
print(f"Channels: {imp_rgb.getNChannels()}")
モジュール 3:マクロの実行

ImageJ マクロ言語(IJM)のコードやマクロファイルを実行します。マクロは ImageJ 環境内で実行され、組み込みの ImageJ コマンドをすべて呼び出せます。

import imagej

ij = imagej.init("sc.fiji:fiji", mode="headless")

# Run an inline macro string
ij.macro.run("print('Hello from ImageJ macro');")

# Run a macro with options string (key=value pairs)
# Options string mirrors the dialog parameters of ImageJ commands
macro_code = """
run("Gaussian Blur...", "sigma=2");
run("Auto Threshold", "method=Otsu white");
"""
ij.macro.run(macro_code)

# Run a macro file from disk
ij.macro.runMacroFile("/scripts/my_analysis.ijm")

# Run macro that returns a value via getResult or output string
result = ij.macro.run("""
x = 42 * 2;
return x;
""")
print(f"Macro returned: {result}")
# Macro with current image: open → process → measure
ij.io().open("/data/cells.tif")   # sets current active image

measure_macro = """
run("Set Measurements...", "area mean min integrated redirect=None decimal=3");
run("Analyze Particles...", "size=50-Infinity display clear summarize");
"""
ij.macro.run(measure_macro)
print("Analyze Particles complete; results in Results table")
モジュール 4:ImageJ Ops

ImageJ Ops は、型安全なディスパッチに対応した 150 以上の画像処理操作を備えるフレームワークです。Ops は ImgLib2 の Img オブジェクトに対して動作し、プログラムから画像処理アルゴリズムを呼び出す際に推奨される方法です。

import imagej
import numpy as np

ij = imagej.init("sc.fiji:fiji", mode="headless")

arr = np.random.randint(100, 900, (512, 512), dtype=np.uint16)
img = ij.py.to_java(arr)   # converts to ImgLib2 RandomAccessibleInterval

# Gaussian blur
blurred = ij.op().filter().gauss(img, 2.0)
blurred_np = ij.py.from_java(blurred)
print(f"Blurred: {blurred_np.shape}")

# Otsu threshold → binary image
binary = ij.op().threshold().otsu(img)
binary_np = ij.py.from_java(binary)
print(f"Binary unique values: {np.unique(binary_np)}")

# Morphological operations
from jnius import autoclass
BitType = autoclass("net.imglib2.type.logic.BitType")
opened = ij.op().morphology().open(binary, [3, 3])
opened_np = ij.py.from_java(opened)
print(f"After opening: {opened_np.shape}")
# Statistics ops
mean_val = ij.op().stats().mean(img)
std_val  = ij.op().stats().stdDev(img)
print(f"Mean intensity: {mean_val:.1f}, StdDev: {std_val:.1f}")

# Math ops: multiply image by scalar
scaled = ij.op().math().multiply(img, ij.py.to_java(2.0))
print(f"Scaled max: {ij.py.from_java(scaled).max()}")
モジュール 5:プラグインとコマンドの呼び出し

SciJava コマンドは、Fiji プラグインをプログラムから呼び出す主要な方法です。コマンドは、プラグインのダイアログに対応する名前付きパラメーターの dict を受け取ります。

import imagej

ij = imagej.init("sc.fiji:fiji", mode="headless")

# Open a file using Bio-Formats opener command
future = ij.command().run(
    "loci.plugins.LociImporter",
    True,
    {"id": "/data/image.lif", "open_files": True, "autoscale": True}
)
module = future.get()
imp = module.getOutput("imp")
print(f"Opened via Bio-Formats: {imp.getDimensions()}")
# Run Analyze Particles as a SciJava command
ij.io().open("/data/binary_mask.tif")

future = ij.command().run(
    "ij.plugin.filter.ParticleAnalyzer",
    True,
    {
        "minSize": 50.0,
        "maxSize": float("inf"),
        "options": 0,      # SHOW_NONE
        "measurements": 1,  # AREA
    }
)
future.get()
print("Analyze Particles command complete")

# Alternatively, run via macro string for simpler plugin invocation
ij.macro.run("""
run("Analyze Particles...", "size=50-Infinity display clear summarize");
""")
モジュール 6:Results テーブルと ROI の分析

Analyze Particles やその他の測定コマンドを実行した後、ImageJ の Results テーブルと ROI Manager から測定結果を取得します。

import imagej
import pandas as pd

ij = imagej.init("sc.fiji:fiji", mode="headless")

# After running Analyze Particles, read the Results table
def results_to_dataframe(ij) -> pd.DataFrame:
    """Convert ImageJ Results table to pandas DataFrame."""
    rt = ij.ResultsTable.getResultsTable()
    if rt is None or rt.size() == 0:
        return pd.DataFrame()
    headings = list(rt.getHeadings())
    data = {col: [rt.getValue(col, i) for i in range(rt.size())]
            for col in headings}
    return pd.DataFrame(data)

# Run segmentation + measurement macro
ij.io().open("/data/cells.tif")
ij.macro.run("""
run("Gaussian Blur...", "sigma=1.5");
setAutoThreshold("Otsu dark");
run("Convert to Mask");
run("Analyze Particles...", "size=20-Infinity display clear");
""")

df = results_to_dataframe(ij)
print(f"Found {len(df)} objects")
print(df[["Area", "Mean", "IntDen"]].describe())
df.to_csv("particle_measurements.csv", index=False)
print("Saved particle_measurements.csv")
# Access the ROI Manager
def get_roi_manager(ij):
    """Return the ImageJ ROI Manager instance, creating if needed."""
    RoiManager = ij.py.jclass("ij.plugin.frame.RoiManager")
    rm = RoiManager.getInstance()
    if rm is None:
        rm = RoiManager(False)   # headless=False means no GUI window
    return rm

rm = get_roi_manager(ij)
roi_count = rm.getCount()
print(f"ROIs in manager: {roi_count}")

# Extract bounding boxes for all ROIs
rois = []
for i in range(roi_count):
    roi = rm.getRoi(i)
    bounds = roi.getBounds()
    rois.append({"index": i, "x": bounds.x, "y": bounds.y,
                 "width": bounds.width, "height": bounds.height})
roi_df = pd.DataFrame(rois)
print(roi_df.head())

よくあるワークフロー

ワークフロー 1:蛍光の自動定量

目標:複数チャンネルの TIFF スタックを開き、ガウシアンぼかしを適用し、核チャンネルをしきい値処理して Analyze Particles を実行し、細胞ごとの測定結果を CSV としてエクスポートします。

import imagej
import pandas as pd
import numpy as np
from pathlib import Path

ij = imagej.init("sc.fiji:fiji", mode="headless")

def quantify_nuclei(tiff_path: str, output_csv: str,
                    channel: int = 1, sigma: float = 1.5,
                    min_size: int = 50) -> pd.DataFrame:
    """
    Segment and measure nuclei in a fluorescence TIFF.

    Parameters
    ----------
    tiff_path  : path to single- or multi-channel TIFF
    output_csv : where to save results
    channel    : 1-based channel index for nuclear stain (e.g., DAPI)
    sigma      : Gaussian blur radius in pixels
    min_size   : minimum nucleus area in pixels
    """
    # Step 1: Open image
    imp = ij.io().open(tiff_path)
    print(f"Loaded: {Path(tiff_path).name}  dims={imp.getDimensions()}")

    # Step 2: Extract channel if multi-channel
    if imp.getNChannels() > 1:
        imp.setC(channel)

    # Step 3: Apply Gaussian blur and threshold via macro
    ij.macro.run(f"""
selectWindow("{imp.getTitle()}");
run("Gaussian Blur...", "sigma={sigma}");
setAutoThreshold("Otsu dark");
run("Convert to Mask");
run("Fill Holes");
run("Watershed");
""")

    # Step 4: Measure
    ij.macro.run(f"""
run("Set Measurements...", "area mean min centroid integrated shape redirect=None decimal=3");
run("Analyze Particles...", "size={min_size}-Infinity display clear include summarize");
""")

    # Step 5: Collect results
    rt = ij.ResultsTable.getResultsTable()
    if rt is None or rt.size() == 0:
        print("No objects detected")
        return pd.DataFrame()

    headings = list(rt.getHeadings())
    df = pd.DataFrame(
        {col: [rt.getValue(col, i) for i in range(rt.size())]
         for col in headings}
    )
    df["source_file"] = Path(tiff_path).stem
    df.to_csv(output_csv, index=False)
    print(f"Saved {len(df)} measurements → {output_csv}")
    return df


df = quantify_nuclei(
    tiff_path="/data/experiment_dapi.tif",
    output_csv="nuclei_measurements.csv",
    channel=1,
    sigma=1.5,
    min_size=50
)
print(df[["Area", "Mean", "Circ."]].describe())
ワークフロー 2:Fiji マクロのバッチ処理

目標:既存の Fiji .ijm マクロファイルを使ってフォルダー内の画像を処理し、各画像の Results テーブルを 1 つの DataFrame にまとめます。

import imagej
import pandas as pd
from pathlib import Path

ij = imagej.init("sc.fiji:fiji", mode="headless")

def run_macro_on_image(ij, image_path: str, macro_file: str) -> pd.DataFrame:
    """Open one image, run a macro file, return its Results table."""
    ij.io().open(image_path)

    # Clear any previous results before running
    ij.macro.run("run(\"Clear Results\");")

    # Run macro file (macro must operate on the active image)
    ij.macro.runMacroFile(macro_file)

    rt = ij.ResultsTable.getResultsTable()
    if rt is None or rt.size() == 0:
        return pd.DataFrame()
    headings = list(rt.getHeadings())
    return pd.DataFrame(
        {col: [rt.getValue(col, i) for i in range(rt.size())]
         for col in headings}
    )


input_dir  = Path("/data/images")
macro_file = "/scripts/measure_cells.ijm"
output_csv = "batch_results.csv"

all_results = []
image_files = sorted(input_dir.glob("*.tif"))

for img_path in image_files:
    print(f"Processing: {img_path.name}")
    df = run_macro_on_image(ij, str(img_path), macro_file)
    if not df.empty:
        df["filename"] = img_path.name
        all_results.append(df)

    # Close all windows to free memory between images
    ij.macro.run("close('*');")

if all_results:
    combined = pd.concat(all_results, ignore_index=True)
    combined.to_csv(output_csv, index=False)
    print(f"Batch complete: {len(image_files)} images, "
          f"{len(combined)} total measurements → {output_csv}")
else:
    print("No results collected from any image")

主なパラメーター

パラメーターモジュールデフォルト範囲/オプション効果
mode初期化"headless""headless", "gui", "interactive"Fiji の GUI ウィンドウを開くかどうかを制御します。スクリプトでは "headless" を使用します
endpoint初期化"sc.fiji:fiji"Maven 座標または /path/to/Fiji.appImageJ2 ディストリビューションを選択します。sc.fiji:fiji には Fiji プラグインがすべて含まれます
sigma(ガウシアンぼかし)マクロ/Ops2.00.5~10.0ピクセル単位の空間平滑化半径です。値を大きくするとノイズが減りますが、エッジもぼやけます
minSize(粒子解析)プラグイン/マクロ0ピクセル²または 0~Infinity対象に含める最小オブジェクト面積です。ノイズ粒子を除去します
method(自動しきい値)マクロ/Ops"Otsu""Otsu", "Triangle", "MaxEntropy", "Huang", "Li"しきい値アルゴリズムです。二峰性ヒストグラムには Otsu が適しています
measurements ビットマスク結果/マクロ変動しますAREA=1、MEAN=2、CENTROID=4 などの OR 結合Results テーブルに表示する列を選択します
Java ヒープサイズ初期化(環境変数)JVM のデフォルト(RAM の約 25%)JAVA_TOOL_OPTIONS で設定大きなスタック画像のメモリを制限します。大きな画像には -Xmx8g を設定します

ベストプラクティス

  1. セッションごとに一度初期化し、ij を再利用します:新しい JVM の起動には時間がかかります(5~15 秒)。モジュールレベルで ij を作成するか、パラメーターとして渡し、ループ内で imagej.init() を呼び出さないようにします。

    # At module top level — initialized once
    import imagej
    ij = imagej.init("sc.fiji:fiji", mode="headless")
    
    def process(path):
        imp = ij.io().open(path)   # reuse ij
        ...
    
  2. Java の管理には conda を使用します:pip のみでインストールすると、JAVA_HOME が設定されていないか、誤った JDK バージョンが PATH に設定されているため、失敗することがよくあります。openjdk=11 を含む conda 環境を使用すると、JVM が見つからないエラーの 90% を回避できます。

  3. バッチループでは、画像ごとに Results と ROI Manager をクリアします:ImageJ は同一セッション内の呼び出し間で結果を蓄積します。行が混在しないように、各画像の処理前に必ず run("Clear Results") と rm.reset() を呼び出します。

    ij.macro.run("run('Clear Results');")
    rm = get_roi_manager(ij)
    rm.reset()
    
  4. 単純なコマンドには ij.command().run() より ij.macro.run() を優先します:マクロ文字列は短く、読みやすく、Fiji Macro Recorder と同じ構文を使用します。コマンドの出力(モジュールの戻り値)にプログラムからアクセスする必要がある場合にのみ、ij.command().run() を使用します。

  5. NumPy への変換はできるだけ後にします:ij.py.from_imageplus() は JVM から Python にデータをコピーします。ImageJ 内で複数の処理を行う場合は、データを ImagePlus または ImgLib2 形式のまま保持し、メモリコピーのオーバーヘッドを最小限に抑えるため、最後にのみ変換します。

  6. ImgLib2 Ops には ij.py.to_java()/ij.py.from_java() を使用します:to_imageplus()/from_imageplus() のペアは従来の ImageProcessor で動作します。一方、to_java()/from_java() は ij.op() が必要とする最新の ImgLib2 型システムを対象とします。

  7. 再現性を確保するため、初期化時に Fiji の更新サイトプラグインリストを設定します:Fiji で新しいプラグイン更新がリリースされてもパイプラインの動作が変わらないよう、sc.fiji:fiji(最新版)ではなく、バージョンを固定した Fiji(sc.fiji:fiji:2.14.0)を指定します。

よく使うレシピ

レシピ:TrackMate によるヘッドレススポット検出

使用場面:TrackMate の粒子追跡をプログラムから実行し、TrackMate の GUI を開かずに検出されたスポットを DataFrame として取得します。

import imagej
import pandas as pd

ij = imagej.init("sc.fiji:fiji", mode="headless")

# TrackMate headless via macro (scripting interface)
trackmate_macro = """
run("TrackMate", "");
// For fully scripted TrackMate, use the Scripting Interface
// documented at https://imagej.net/plugins/trackmate/scripting
"""

# Scripted TrackMate via Jython-style Java interop
def run_trackmate_headless(ij, imp, radius=3.0, threshold=100.0):
    """Detect spots with LoG detector; return DataFrame of spot coordinates."""
    from jnius import autoclass

    # Import TrackMate classes
    Model          = autoclass("fiji.plugin.trackmate.Model")
    Settings       = autoclass("fiji.plugin.trackmate.Settings")
    TrackMate      = autoclass("fiji.plugin.trackmate.TrackMate")
    LogDetectorFactory = autoclass(
        "fiji.plugin.trackmate.detection.LogDetectorFactory")

    model    = Model()
    settings = Settings(imp)

    # Configure LoG spot detector
    settings.detectorFactory = LogDetectorFactory()
    settings.detectorSettings = {
        "DO_SUBPIXEL_LOCALIZATION": True,
        "RADIUS": radius,
        "TARGET_CHANNEL": 1,
        "THRESHOLD": threshold,
        "DO_MEDIAN_FILTERING": False,
    }

    tm = TrackMate(model, settings)
    tm.process()

    # Extract spot table
    spots = model.getSpots()
    spots.setVisible(True)
    records = []
    for spot in spots.iterable(True):
        records.append({
            "id":       spot.ID(),
            "x":        spot.getDoublePosition(0),
            "y":        spot.getDoublePosition(1),
            "z":        spot.getDoublePosition(2),
            "frame":    spot.getFeature("FRAME"),
            "quality":  spot.getFeature("QUALITY"),
        })
    return pd.DataFrame(records)


imp = ij.io().open("/data/timelapse.tif")
df  = run_trackmate_headless(ij, imp, radius=3.0, threshold=50.0)
print(f"Detected {len(df)} spots across {df['frame'].nunique()} frames")
df.to_csv("spots.csv", index=False)
print(df.head())
レシピ:ImageJ ハイパースタックを NumPy の 5D 配列(TZCYX)に変換

使用場面:多次元の Fiji ハイパースタックを Python にインポートし、ほとんどの科学画像解析ライブラリで使用される標準的な TZCYX 軸順の NumPy 5D 配列にします。

import imagej
import numpy as np

ij = imagej.init("sc.fiji:fiji", mode="headless")

def hyperstack_to_numpy(ij, imp) -> np.ndarray:
    """
    Convert an ImageJ hyperstack to a NumPy array with shape (T, Z, C, Y, X).

    ImageJ internal order is C-Z-T (slowest to fastest in stack index).
    This function reorders to the TZCYX convention used by tifffile, OME, etc.
    """
    nC = imp.getNChannels()
    nZ = imp.getNSlices()
    nT = imp.getNFrames()
    H  = imp.getHeight()
    W  = imp.getWidth()

    arr = np.zeros((nT, nZ, nC, H, W), dtype=np.uint16)

    for t in range(1, nT + 1):
        for z in range(1, nZ + 1):
            for c in range(1, nC + 1):
                idx = imp.getStackIndex(c, z, t)
                imp.setSlice(idx)
                arr[t-1, z-1, c-1] = ij.py.from_imageplus(imp)

    return arr


imp = ij.io().open("/data/4d_experiment.tif")
print(f"ImageJ dims (W,H,C,Z,T): {imp.getDimensions()}")

stack = hyperstack_to_numpy(ij, imp)
print(f"NumPy TZCYX shape: {stack.shape}")  # e.g., (10, 15, 2, 512, 512)
print(f"dtype: {stack.dtype}, max: {stack.max()}")

# Save as OME-TIFF with correct axis metadata
import tifffile
tifffile.imwrite(
    "output_TZCYX.ome.tif",
    stack,
    imagej=True,
    metadata={"axes": "TZCYX"},
    photometric="minisblack"
)
print("Saved output_TZCYX.ome.tif")

トラブルシューティング

問題原因解決策
初期化時に JVMNotFoundException が発生するJAVA_HOME が設定されていないか、JDK のバージョンが正しくありませんconda でインストールします:conda install -c conda-forge openjdk=11。Java 17 は避けてください
RuntimeError: Fiji download failedインターネットに接続できないか、企業プロキシが原因ですfiji.sc から Fiji を手動でダウンロードし、imagej.init("/path/to/Fiji.app") を使用します
大きなスタックで java.lang.OutOfMemoryError が発生するJVM のデフォルトヒープが小さすぎますimagej をインポートする前に export JAVA_TOOL_OPTIONS="-Xmx8g" を設定します
マクロの run(...) が何もせずに終了するマクロが画像を想定しているのに、アクティブな画像がありません処理マクロを実行する前に ij.io().open(path) を呼び出します。ij.WindowManager.getImageCount() を確認してください
Analyze Particles の実行後、結果テーブルが空になるしきい値が適用されていないか、マスクがバイナリではありませんマスクが 8 ビットのバイナリ(0/255)であることを imp.getType() == 0 で確認します。Analyze Particles の前に Convert to Mask を実行してください
ij.ResultsTable.getResultsTable() で AttributeError: 'NoneType' object が発生するこのセッションではまだ測定が実行されていませんAnalyze Particles マクロが完了したことを確認します。ij.macro.run("print(nResults);") を実行して件数を確認してください
プラグインクラスが見つからない(ClassNotFoundException)この Fiji インストールにプラグインがありませんFiji のアップデートサイト(例:TrackMate)を追加するか、すべてのデフォルトプラグインが含まれる sc.fiji:fiji エンドポイントを使用します
gui モードが HeadlessException でクラッシュするディスプレイを利用できません(SSH/クラスター)リモート環境では mode="headless" を使用します。GUI モードには DISPLAY または X11 フォワーディングが必要です

関連スキル

  • scikit-image-processing — JVM を使わない純粋な Python 画像処理です。Fiji プラグインが不要な場合に使用します
  • napari-image-viewer — Python 用のインタラクティブな多次元画像ビューアーです。可視化において PyImageJ を補完します
  • trackpy-particle-tracking — Python ネイティブの Crocker-Grier SPT です。単純な 2D トラッキングでは TrackMate の代替になります
  • cellpose-cell-segmentation — 深層学習による細胞セグメンテーションです。単独で実行することも、Fiji プラグインとして実行することもできます
  • omero-integration — OMERO サーバーによる画像管理です。PyImageJ では omero-py 経由で取得した画像を処理できます

参考資料

コメント