見出し画像

【ImageJ】ImageJマクロを使って輝度プロファイルを取得する

生命科学系研究者のえいこです。今回はImageJマクロを使って、画像の輝度プロファイルを取得してみようと思います。

参考にしているのは、「ImageJではじめる生物画像解析」。

輝度プロットを手動で取得する手順は、こちらの記事で紹介しています。

これをImageJマクロをでやってみよう!と言うのがこの記事の主旨です。

ImageJマクロで輝度プロットを取得する

手順としては、

1. m51.tifファイルを開く
2. 中央の明るい部分を通るように直線をひく
3. マクロのコードを入力して実行する

1. と2.の手順は以前の記事で紹介しているので割愛します。輝度プロットを取得するImageJマクロのコードを書いていきます。(ImageJマクロのスクリプトを各画面を開く手順はこちらの記事で紹介しています)

〜輝度プロットを取得するコード〜

pf = getProfile();
xs = newArray(pf.length);
for (i = 0; i < xs.length; i += 1){
    xs[i] = i;
}
Fit.doFit("Gaussian", xs, pf);
Fit.plot;

一行目の"getProfile()"はアクティブな画像上の直線領域に沿った輝度プロファイルを取得して、一次元の数値の並び(Array)にして返すと言う関数。その数値の並びを"pf"と言う変数に入れているのが一行目の作業です。これでy軸の設定が完了!

二行目の"newArray()"は新しい数値の並びを、準備する関数です。引数に"pf.length"を指定することで、pfの長さと同じ長さの数値の並び(の空箱)を"xs"と言う変数に入れています。これでx軸の設定が完了しました。

三行目から五行目はfor文です。"xs"に準備した空箱に、0から順番に1, 2, 3, 4,....と数値を一つずつ入れていっている作業です。

六行目の"Fit.doFit()"は近似させる関数を指定して、どれくらい近似しているのか検証することができる関数です。引数は"Fit.doFit(equation ,xpoints, ypoints)"で指定します。equation(等式)は等式、y=x+1のように指定します。今回のように、"Gaussian"でも指定できます。xpointsはx軸を指定するので、"xs"、ypointsはy軸を設定するので"pf"としておきます。

Gaussian分布とは?
ガウス分布とは平均と分散によって定義された正規分布のこと。左右対称の釣鐘状のプロットです。今回は「どれくらい正規分布に近いか?」を検証するために"Gaussian"と指定しています。

七行目の"Fit.plot"でグラフを図示します。

画像1

どれくらい正規分布と近似しているのかわかるグラフが描けました!

と、テキストではここまでしか書かれていなかったのですが...画像を開く、直線を引くもマクロでできるのでは?と思い、コードに起こしてみます。ついでに、上記のコードでやっていることを一つ一つ検証していこうと思います。

【おまけ】サンプル画像を開くことからマクロでやってみる

さて、0からマクロをどうやって組んでいくかですが...[Plugins -> Macros -> Record...]を開くとマクロのレコーダーが立ち上がって、やっている作業をマクロのスクリプトに起こしてくれます。

これを利用して、画像を開いて直線を書くスクリプトを書きました。

run("M51 Galaxy (16-bits)");
//setTool("line");
makeLine(154, 0, 154, 510);
※"//"を前につけるとコメントアウトとなって、実行の対象にはなりません。

これで自動的に画像が開いて、直線を書いてくれるようになりました。しかも、直線は数値を指定しているので毎回同じ場所に描かれると言うメリットもあります。

さて、マクロで画像を開いて直線を引けるようになりました。が、【おまけ】のもう一つの目的である、書いたコードで具体的にどんなことが行われているのか検証していく、をしていきたいと思います。

コードの一行目、"getProfile()"で具体的にどんなものが取得されているのか見てみたいと思います。"getProfile()"はArrayの形で返すと言うことだったので、Arrayを表示させる関数"Array.print()"で実行してみたいと思います。

pf = getProfile();
Array.print(pf);

を実行すると、LogウィンドウにArrayが表示されます。

スクリーンショット 2021-01-02 6.06.01

一つ一つの数値が、各ピクセルの輝度になっています。ではこの数字、いくつ続いているのでしょう?"print(pf.length)"を実行してみてみると、Log画面に"510"と表示されました。

次に、コードの二行目"newArray(pf.length)"はどんな作業なんでしょう?先ほどと同じように"Array.print(xs)"を実行してみてみます。

xs = newArray(pf.length);
Array.print(xs);

スクリーンショット 2021-01-02 6.08.02

これも、長さを確かめるために"print(xs.length)"を実行すると"510"と表示されました。つまり、0が入った510個の箱が準備されたと言うことですね。

最後に、三行目から五行目のfor文でやっていることを検証していきましょう。先ほどと同じように、for文を回した後"Array.print(xs)"を実行してみます。

for (i = 0; i < xs.length; i++){
	xs[i] = i;
}
Array.print(xs);

スクリーンショット 2021-01-02 6.09.18

0から順番に数値が入って行っているのがわかります。"print(xs.length)"で長さを確かめてみるとやはり"510"と表示されました。

これで、検証完了です♪


マクロを少しずつ使えるようになってきました。次回は、Lookup Tablesについて勉強してみようと思っています。

それでは、また!


ImageJマクロの関数については、下記のサイトを参考にしました。


最後までお読みいただきありがとうございます。よろしければ「スキ」していただけると嬉しいです。 いただいたサポートはNGS解析をするための個人用Macを買うのに使いたいと思います。これからもRの勉強過程やワーママ研究者目線のリアルな現実を発信していきます。