ImageJで塗りつぶした領域に番号を振り、楕円に近似して長径と短径を求める

投稿日:2021/4/4
サムネイル画像

手動で塗りつぶした部分に番号を振り、別の画像として保存。さらに楕円に近似して長径と短径を求めるImageJマクロの紹介記事です。

マウス臓器にできた腫瘍をカウントし、楕円体と仮定して体積を算出する際に使用したマクロです。 しかし他の用途でも使えると思いますので、コピペして必要に応じてアレンジしてお使いください。

1.このマクロが役立つ場面

本記事のマクロが出来ることは以下の2つです。

  • ・黒く塗りつぶした複数の領域に番号を振り、別画像として保存
  • ・それぞれの領域を楕円に近似し、長径と短径を測定したリストをクリップボードにコピー
  • マウスの臓器にできた腫瘍の数と体積を求める際に使ったマクロなのですが、 臓器の写真をインターネットに上げるのもアレなので、別の画像を使用することにします。

    こちらは入居時点で床についていた傷を記録するために撮った画像です。こんな所で役に立つなんて思いもしませんでした。
    説明に使用するサンプル画像

    本記事では腫瘍ではなく、床の傷をカウントすることにします。「いい感じの閾値を決め、黒い部分を認識する」 という発想でコードを書けばいい気もしますが、以下の理由で(少なくとも私には)困難です。

  • ・光の当たり具合にムラがある
  • ・フローリングの線も黒い
  • ・判断が微妙な小さな傷がある
  • また、メラノーマの腫瘍に関してはメラニンの関係で黒と白が混在する場合があるという事情もあり、 「判断して塗りつぶすのは手動。カウントと測定だけマクロに任せよう」と考えました。 ちなみに楕円に近似する理由は、腫瘍を評価する際に楕円体の体積の公式を使って算出している論文が多く、それに倣うためです。

    2.使い方

    2-1. ROIマネージャーの設定

    ROIマネージャーを起動(Ctrl+T)して、"More"→"Labels"とクリック。
    ROIマネージャーにおけるMoreとLabelsの場所

    ColorはwhiteFont sizeは18show labelsだけチェックを入れ、OKをクリック。(マクロ実行後に保存された画像の数字が小さい場合は、Font sizeを大きくして再度やり直してください)
    Labelsの設定例

    2-2. スケールバーの設定

    定規など長さが分かる物が画像に含まれている場合は、スケールバーの設定を事前に行うと良いです。私は実験データとなる写真を取る際には、方眼紙を下に敷いたりしてました。 方法は「ImageJ スケールバー 設定」でググると出てきます。

    長径・短径を測る必要が無い場合、長さがある物が画像に含まれていない場合は、スケールバーの設定はしなくてOKです。

    2-3. カウントしたい領域を塗る

    Brush widthを30以上ColorをBlackにする。(このマクロではブラシサイズ30以上の太さで塗られた黒い領域を認識するため)
    ブラシの設定

    カウント(および測定)したい領域を塗る
    塗りつぶした画像

    2-4. マクロの実行

    以下のマクロを実行する。ImageJマクロの使い方についてはこちら(別タブで開きます)。

    run("Select All");
    run("8-bit");
    
    //黒色が716ピクセル以上隣接している領域を選択する
    run("Threshold...");
    setThreshold(0, 0);
    roiManager("Show All with labels");
    run("Analyze Particles...", "size=715-Infinity pixel show = Ellipses clear add");
    
    //ユーザーがOKを押すまで一時停止
    title = "Wait for user";
    msg = "Delete non-tumor, then click OK";
    waitForUser(title, msg);
    
    //ファイルのディレクトリと拡張子を取得(拡張子はピリオドを含めた状態で取得)
    path = getDirectory("image");
    name = getInfo("image.filename");
    idx = lastIndexOf(name, ".");
    extName = substring(name, idx);
    
    //ファイル名の末尾を"marked.jpg"にしてJPEG画像として保存
    run("Flatten"); //ROIマネージャーでラベリングした情報を含めた画像を得る
    saveAs("Jpeg", path+replace(name, extName, "marked.jpg"));
    
    //面積および楕円体に近似した際の長径と短径をクリックボードにコピー
    run("Set Measurements...", "area fit redirect=None decimal=3");
    roiManager("Measure");
    String.copyResults();
    
    //2枚の画像ウィンドウを閉じる。ROIやResultsウィンドウは閉じなくとも問題ない
    close();
    close();

    次のような画面になります。もし意図しない領域が選択されていたらROIマネージャーで選んでDeleteしてください。自分で塗った領域だけが選択されている状態になったら、OKをクリックユーザー確認画面

    以上で完了です。ファイル名の末尾にmarked.jpgと付いた新しい画像が保存されているはずです。

    また、Resultsというウィンドウの内容がクリップボードに保存されているはずですのでExcel等に貼り付けることができます。各項目の意味は以下の通りです。

  • ・Area:面積
  • ・Major:楕円に近似した際の長径
  • ・Minor:楕円に近似した際の短径
  • ・Angle:長径の角度(X軸方向に対して)
  • なお、面積や長さのデフォルトの単位はピクセル数で、Set Scaleを行った場合はその際に指定した単位です。

    2-5. 次の画像で行うとき

    引き続き、別の画像で解析をする場合、2-1. ROIマネージャーの設定2-2. スケールバーの設定は 不要で、2-3. カウントしたい領域を塗るから行えばOKです。

    一度ImageJを閉じてしまうと、再度2-1. ROIマネージャーの設定から設定し直す必要があります。

    3.マクロを使わない場合の操作【読まなくてOK】

    マクロの行数と、それを手動でやる場合の手順を書いておきます。

    【2行目】"Image"→"Type"→"8bit"(白黒8ビット画像にする)
    【5行目】"Image"→"Adjust"→"Threshold"(閾値設定を開く)
    【6行目】画面の上の値を0、下の値を5、チェックボックスは付けない状態でApply (0が黒、255が白です。0~0ではなく0~5で上手くいきました。必要に応じて微調整してください)
    【7行目】ROIマネージャーを起動し、ShowAllとLabelsにチェックを入れる
    【8行目】"Analyze"→"Analyze Particles"をクリック。Sizeは715-Infinity、Circularityは0.00-1.00、 ShowはNothing、チェックはClear resultsとAdd to Managerだけに付けて、OKをクリック。
    【22行目】ROIマネージャーで"Flatten"をクリック。
    【23行目】Jpegとして名前を付けて保存。
    【26行目】"Analyze"→"Set Measurements"で、AreaとFit ellipseだけにチェックを付けてOKをクリック。
    【27行目】"Analyze"→"Measure"
    【28行目】Resultsの全範囲を選択してコピー

    以上、ImageJで塗りつぶした領域に番号を振り、楕円に近似して長径と短径を求める方法でした。 この方法を使うことで、画像のどの部分をカウントして、それぞれの大きさをいくつと評価したのか? という記録を画像として残すことができます。もし似たようなことをImageJでやりたい人の目に止まれば嬉しいです。

    ページの一番上に戻る