0
0

More than 1 year has passed since last update.

Jupyter コンテナをカスタマイズして PyImageJ を動作させる

Posted at

1. はじめに

顕微鏡観察等の画像解析に広く利用される ImageJ (JAVAの仮想マシン上で動作)とOpenCV, scikit-image などの Python 画像処理ライブラリとを連携させるため、PyImageJ をインストールした JupyterLab の Docker コンテナ環境を構築しました。

docker コマンドが使用できる環境であれば、Python ラッパー関数を提供する PyImageJ を使用して、 ImageJ の機能を Python ノートブック上でお手軽に試すことができます。

ここでは、OpenCV による白黒二値化処理と ImageJ による粒子解析を組み合わせた参考事例を紹介します。

2. 動作テスト

2.1. JupyterLab サーバー起動

ターミナルを開き、カレントディレクトリに notebooks ディレクトリを作成しましょう。

次に、以下の docker コマンドを入力します。
ユーザー権限の問題が生じないように、環境変数 NB_UID および NB_GID に、ホストユーザーの UID / GID の値を設定しましょう。

 docker run -it \
  --env NB_UID=1000 \
  --env NB_GID=100 \
  -p 8888:8888 \
  --name jupyterlab \
  -v $PWD/notebooks:/notebooks  \
  ken2s/jupyterlab

しばらくすると、ターミナルに以下のような、アクセス先と <token> が表示されます。

 http://<hostname>:8888/lab?token=<token>

Webブラウザで http://localhost:8888 を開いて Password or token:<token> を入力、もしくは、 http://127.0.0.1:8888/lab?token=<token> をそのまま開くことで、JupteLab サーバーにアクセスできます。

notebooks

ImageJ の インストールに伴って JupteLab の Launcher メニューは賑やかなものとなります。

2.2. PyImageJ テスト

Python ノートブックを新規に開き、セルに以下のコードを入力して実行すれば、PyImageJ テストが可能です。

# Create an ImageJ2 gateway with the newest available version of ImageJ2.
import imagej
ij = imagej.init()
print(f"ImageJ version: {ij.getVersion()}")

ImageJ version: 2.5.0/1.53r のようにバージョン情報が表示されたらテスト完了です。

3. 画像解析例

ここでは、ImageJ の サンプル画像 blobs.gif を使用した画像解析例を示します。
ノートブック全文を、blobs_segmentation.ipynb に示します。

3.1. 初期化・Plugin読込み ImageJ

ImageJ を初期化するとともに、Plugin を読み込みます。
詳細は、PyImageJ のドキュメントを確認しましょう。

import imagej
import scyjava as sj

# initialize imagej
ij = imagej.init(mode="headless", add_legacy=True)
print(f"ImageJ version: {ij.getVersion()}")

# get additional resources
HyperSphereShape = sj.jimport("net.imglib2.algorithm.neighborhood.HyperSphereShape")
Overlay = sj.jimport("ij.gui.Overlay")
Table = sj.jimport("org.scijava.table.Table")
ParticleAnalyzer = sj.jimport("ij.plugin.filter.ParticleAnalyzer")

3.2. イメージ読込み ImageJ

ImageJ でサンプル画像を読み込み、表示します。

# Load the image
url_img = "https://imagej.nih.gov/ij/images/blobs.gif"
img_ij = ij.io().open(url_img)

# Display the image
ij.py.show(img_ij)

サンプル画像

3.3. 画像変換 ImageJ -> Python

ImageJ で読み込んだ画像を OpenCV で扱うため、 xarray, ndarray に変換します。

import cv2
import xarray as xr

# Send the image to Python
img_xr = ij.py.from_java(img_ij)

# convert the array from xarray to ndarray
img_np = xr.DataArray.to_numpy(img_xr)

3.4. 前処理・白黒二値化 Python

OpenCV によって、グレー画像に変換し、ヒストグラム平坦化、ガウシアンぼかし処理後、白黒二値化画像に変換します。さらに、粒子解析の際に粒子(白色)を認識させるために白黒画像を反転させます。

# convert to grayscale image
img_gray = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)

# Equalizes the histogram of a grayscale image
# using Contrast Limited Adaptive Histogram Equalization
clahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))
img_clahe = clahe.apply(img_gray)

# GaussianBlur
img_blur = cv2.GaussianBlur(img_gray, ksize=(5, 5), sigmaX=0)

# threshold
ret, img_th = cv2.threshold(img_blur, 0, 255, cv2.THRESH_OTSU)

# inverse image
img_inv = cv2.bitwise_not(img_th)

# Display the image
ij.py.show(img_inv, "gray")

白黒二値化反転画像

3.5. 画像変換 Python -> ImageJ

再度、画像を ImageJ で扱うために変換します。

# Converting Python objects to Java
img_java = ij.py.to_java(img_inv)

# convert ImgPlus to ImagePlus
img_imp = ij.py.to_imageplus(img_java)

3.6. 粒子解析 ImageJ

ImageJ による粒子解析を実行します。

# get ResultsTable and set ParticleAnalyzer
rt = ij.ResultsTable.getResultsTable()
ParticleAnalyzer.setResultsTable(rt)

# set measurements
ij.IJ.run("Set Measurements...", "area center shape")

# run the analyze particle plugin
ij.py.run_plugin(
    plugin="Analyze Particles...",
    args="size=0-Infinity circularity=0.00-1.00 clear",
    imp=img_imp,
)

3.7. データ変換 ImageJ -> Python

解析データを pandas daterffreme に変換します。

# convert results table -> scijava table
sci_table = ij.convert().convert(rt, Table)

# scijava table -> pandas dataframe
df = ij.py.from_java(sci_table)

3.8. 解析結果 Python

# print dataframe
df
     Area          XM          YM     Circ.        AR     Round  Solidity
0   426.0   20.575117   13.645540  0.663245  2.081601  0.480400  0.881988
1   183.0   63.521858    4.734973  0.754354  1.776324  0.562960  0.950649
2   659.0  108.812595   13.053869  0.863307  1.066680  0.937488  0.966985
3   432.0  154.972222   10.270833  0.867364  1.060849  0.942641  0.960000
4   471.0  247.385350   13.954352  0.810489  1.578974  0.633323  0.964176
..    ...         ...         ...       ...       ...       ...       ...
57  211.0   46.533175  241.007109  0.939930  1.271582  0.786422  0.944072
58   77.0  179.136364  251.668831  0.593288  3.067080  0.326043  0.900585
59   88.0  128.352273  251.795455  0.488962  3.937549  0.253965  0.936170
60   50.0  234.760000  252.000000  0.630967  2.603278  0.384131  0.909091
61   46.0   74.152174  252.391304  0.539673  4.022377  0.248609  0.893204

[62 rows x 7 columns]

解析結果の各項目は、以下のとおりです。

  • Area : Area (面積)
  • XM, YM : Centroid (重心の座標)
  • Circ. : Cicularity (真円度)
  • AR : Aspect Ratio (アスペクト比)
  • Roundness : Roundness (円形度)
  • Solidity : Solidity (凸度)

各項目の定義式等を確認する際には、 ImageJ のドキュメントを参照しましょう。

4. Docker コンテナ・イメージ解説

Dockerfile を以下に示します。
少々トリッキーな設定を含みます(後述)。

最新の Dockerfilegithub を参照しましょう。

FROM jupyter/scipy-notebook

USER ${NB_USER}

WORKDIR /tmp

ENV CONDA_DIR=/opt/conda
ENV JAVA_HOME=/opt/conda/jre

COPY --chown=${NB_UID}:${NB_GID} requirements.txt ./
RUN pip install --upgrade pip  &&\
    pip install --quiet --no-cache-dir -r ./requirements.txt

RUN conda install beakerx openjdk=8 pyimagej rise \
    jupyter_contrib_nbextensions -c conda-forge -y &&\
    conda clean -i -t -y

RUN pip install --quiet --no-cache-dir git+https://github.com/imagej/pyimagej.git@master &&\
    wget https://raw.githubusercontent.com/imagej/pyimagej/master/doc/Puncta-Segmentation.ipynb &&\
    wget https://raw.githubusercontent.com/imagej/pyimagej/master/doc/sample-data/test_still.tif &&\
    mkdir sample-data &&\
    mv test_still.tif sample-data &&\
    jupyter nbconvert --to python Puncta-Segmentation.ipynb &&\
    python Puncta-Segmentation.py

RUN fix-permissions "${CONDA_DIR}" &&\
    fix-permissions "/home/${NB_USER}"

WORKDIR /notebooks

EXPOSE 8888
  • ベースとなる image は jupyter/scipy-notebook です。
  • コンテナ内の user は jovyan となります。
  • PyImageJ 公式ドキュメント では、conda + mamba 仮想環境 によるインストールが推奨されていますが、本コンテナでは 仮想環境を使用していません。
  • 本記事執筆時点の最新版 PyImageJ 1.2.1 では、求める機能に不具合があったため、github から、最新コードを取り込みました。(PyImageJのバージョンアップ確認後、Docker イメージ見直し予定)
  • コンテナ起動直後の imagej.init() 時に、数分かかること(Marven キャッシュ生成 ?)があるため、イメージ作成時にサンプルプログラムを実行させて、 imagej.init() の時短をはかりました。
  • pipでインストールしたモジュールは、 requirements.txt を参照しましょう。

5. おわりに

ImageJ, Python, JupyterLab の組み合わせた Docker コンテナ・イメージを作成し、OpenCV による画像処理と ImageJ による粒子解析を組み合わせた事例を紹介しました。

公開先

更新履歴

  • 2022/07/01 初稿

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0