その漫画自炊オタクはImageJマクロに恋をする

プログラミングを用いた、自炊漫画の画像処理

【コード解説】ImageJのMacroをいじるために必要な知識

 

f:id:yu3xx:20200624020438j:plain

 

ImageJのマクロで使われるコードをいくつか抜粋して、簡単な解説を添えました。

 

いままで公開したMacroで使っている命令はだいたい網羅しています。

色々カスタマイズしたい時のヒントに。

 

 

2021.12.07 アップデート ... 未掲載分をいくつか追加しました。

 

 

「これからImageJマクロ作りを始めてみたいので、キソから知りたい!」という方は、下の基礎編シリーズも覗いてみてください! 

 

 

 

※ txtファイルにコピペしておくと使い勝手が良いと思います

//		//コメント。行内で//以降の記述は無視される。

==		//等しい。

!=		//等しくない。

>		//〜より大きい。

>=		//〜以上。

<		//〜より小さい。

<=		//〜以下。

++		//インクリメント。1増やす。

--		//ディクリメント。1減らす。

+=		//a+=1はa=a+1

&&		//かつ。AND。

||		//または。OR。

1+1		//足し算。2

2-1		//引き算。1

3/2		//割り算。1.5

4%3		//割り算の余り。1

5*2		//掛け算。10

	

abs(数値);		//指定した数値の絶対値を返す。


Array.copy(X);		//配列Xを値渡しコピーした配列を返す。コピー先の配列は、newArrayで配列宣言しなくてOK。勝手に配列になる。


Array.print(X);		//配列Xの中身をLogウィンドウに表示する。


Array.show(X);		////配列Xの中身を、新しいウィンドウに表として表示する。


atan(数値);		//指定した数値のアークタンジェントを返す。


beep();		//ビープ音を鳴らす。


bitDepth();		//画像信号値のbit数を返す。8,16,24,32のどれか。


break;		//一番内側のforループを、全周回スキップしてループから抜ける。


close();		//アクティブなimageウィンドウを閉じる。()内にファイル名を入れてimageを指定することも出来る。


continue;		//一番内側のforループを、今回のループだけスキップして次ループへ。


d2s(数値,小数点以下の第何位か);		//ある数値を小数点以下第何位までの値として四捨五入するか指定できる。例えばd2s(1.781,2)だと1.78、d2s(1.781,1)だと1.8。ただしd2sはdouble to stringの略なので、結果は文字列となることに注意。数値として扱いたいならparseFloatが必要。


Dialog.addCheckbox("文章",初期値);		//ダイアログに文章を添えたチェックボックスを作成。


Dialog.addNumber("文章",初期値);		//ダイアログに文章を添えた数値入力領域を作成。


Dialog.addRadioButtonGroup("文章",items,行,列,デフォルト);		//ダイアログに文章を添えたラジオボタンを、行×列レイアウトで作成。事前にitemsに配列を作成して準備しておく。Items = newArray("選択肢A","選択肢B")


Dialog.addString("文章",初期値);		//ダイアログに文章を添えた文字列入力領域を作成。


Dialog.create("文章");		//文章をタイトルにしたダイアログ画面を作成。ダイアログ作成はcreate→add複数個→show→get複数個の順番で。


Dialog.getCheckbox();		//ダイアログにチェックをしてたら1,してなかったら0を変数に返す


Dialog.getNumber();		//ダイアログに入力した値を変数に返す


Dialog.getRadioButtonGroup();		//ダイアログで選択した文字列を変数に返す


Dialog.getString();		//ダイアログに入力した文字列を変数に返す


Dialog.show;		//addなにがしで準備したダイアログを表示。入力させる。この後、Dialog.getなにがしで入力情報を拾っていくが、addなにがしで命令した順番でgetなにがしを命令すると、正しい情報を拾ってくれる。




do{		//条件を満たす限り、命令を繰り返す。
	命令文;
}while(条件);



endsWith(調べたい文字列,文字or文字列);		//調べたい文字列が、指定した「文字or文字列」で終わるなら1(true),終わらないなら0(false)を返す。変数で1か0で受けても良いし、If内で直接使ってもOK。


exit("文章");		//ポップアップに文章を表示させ、マクロを強制終了する。


File.copy(パスA,パスB);		//パスAで指定されるファイルを、パスBで指定される場所・ファイル名でコピー移動させる。Imageを開いてなくても実行できる。


File.exists(パス);		//パスで指定したディレクトリが存在するなら1,しないなら0を返す。if(!File.exists(subDir))とすると、subDirが存在しない時だけ命令を実行できる。


File.makeDirectory(パス);		//パスで指定した位置にディレクトリを作成する。


floor(数値);		//数値を小数点以下切り捨てする。



for(i=0; i<100; i++){		//iが0から99まで、iを1ずつ増やしながら指定した命令を実行する。
	print(i);
}	



getAgetArgument();		//あるマクロから別のマクロをrunMacro(macro名,arg)で起動する際にargとして指定した文字列や、toolのメニューバーから選択した文字列を、マクロ内で任意の入れ物に格納する時に使う。


getBoundingRect(x,y,width,height);		//設定した長方形ROIの情報を変数に取得する。ROIの左上スミの座標をx,yに、ROIのタテヨコ幅をwidth,heightに格納する。


getDateAndTime(year,month,dayOfWeek,dayOfMonth,hour,minute,second,msec);		//現在の年月日時刻を、()内に指定した変数に順番に格納する。monthだけ0からカウントするので、month=5は6月。


getDirectory("タイトル");		//「タイトル」と名付けたフォルダ選択画面を表示し、選択したフォルダのパスを「文字列」として変数に返す。


getFileList(ディレクトリのパス);		//指定したディレクトリ配下のファイル名及びディレクトリ名を配列の各要素に格納。ディレクトリの場合は、ディレクトリ名の最後に『/』を追加して格納する。


getHeight();		//画像のHeight(タテ)方向Pixel数を返す。height=100ならyは0-99。


getHistogram(values,counts,nBins,histMin,histMax);		//histMinからhistMaxまでをnBins個に等分した階級を持つヒストグラムを作成する。階級は配列valueに、度数は配列countsに格納される。たとえばnBins=1000, histMin=-1000, histMax=1000なら-1000から999までの2000個に等分。


getInfo("0008,0020");		//指定したDICOM Tagの情報を文字列として取得する。


getNumber("ラベル", 初期値);		//数値入力領域を表示させ、入力した値を変数に渡す。


getPixel(x,y);		//画像上の(x,y)のピクセル値を変数に返す。


getStatistics(area,mean,min,max,std,histgram);		//選択したROI内もしくは画像全体の、面積や平均値などを指定した変数に順番に取得・格納する。取得する順番さえ変えなければ、後ろ側の省略も可。getStatistics(area,mean)とか。


getString("ラベル", 初期値);		//文字列入力領域を表示させ、入力した文字列を変数に渡す。


getTitle();		//アクティブなimageのファイル名(拡張子含む)を文字列として返す。


getWidth();		//画像のWidth(ヨコ)方向Pixel数を返す。width=100ならxは0-99。


if(a == 10) print("hoge");		//もしaが10なら、hogeと表示する。複数命令を実行するときは{}で囲う。ifは小文字なので注意。




if(条件){		//もし〜なら○○、そうじゃないなら××。
	命令文○○;
}else{
	命令文××;
}



IJ.currentMemory();		//ImageJが現在使用しているメモリ量を返す。


imageCalculator("Subtract create", "画像1","画像2");		//画像の差分。画像1-画像2。


lastIndexOf(調べたい文字列,文字列or文字);		//調べたい文字列の中で、「指定した文字列もしくは文字」が最後に出てくるのが何番目なのかを、0番から数えた数値で返す。


lengthOf(文字列);		//対象とする文字列の文字数を返す。hogeなら4。


makeRectangle(x, y, width, height);		//始点が(x,y)で幅width,高さheightの矩形ROIを設定する。


newArray(1,4,7);		//要素が1,4,7である配列を作成する。


newArray(n);		//要素の数がn個である配列を作成する。


open(パス);		//パスで指定されるimageを開く。


parseInt(文字列);		//文字列で表された数字を、整数に変換する。


pow(n,a);		//nのa乗を返す。


print(変数や文字列);		//Log画面に,変数に格納された値を表示する。文字列を表示するなら" "で囲う。コンマや+で区切ると複数の内容を追加表示できる。※ただし、print内で数値や文字列の足し算をする際に使う+とごっちゃにならないように注意。(コンマを使っているかどうかをみて、機械が勝手に判別してくれる)


print("\\Update:”,変数);		//最初に”\\Update:”とつけることで、Log画面に表示する際に新たに行を追加して表示するのではなく、最終行に上書きして表示するようになる。普通のprintと同じく、コンマや+で区切ると複数の変数や文字列を追加表示できる。


Plot.create(“Title”,”xLabel”,”yLabel”,xArray,yArray);		//ヨコ軸に配列xArray、タテ軸に配列yArrayのグラフをプロットするための準備。このあとPlot.show();するとグラフが表示される。


Plot.show();		//Plot.createで準備したグラフを表示させる。


random();		//0〜1の値(小数)をランダムに返す。擬似的な一様分布の乱数。0ジャストと1ジャストは含まない。


rename(文字列);		//アクティブなimageのファイル名を、文字列で指定した名前に変更する。


replace(文字列,文字列A,文字列B);		//対象とする文字列の中で、「文字列A」の部分を「文字列B」で置換する。


return 変数;		//自作関数で計算した値を、関数の返り値として外に出す。return出来る返り値はきほん1つだけ。


return 配列;		//配列を返り値として外に出す(参照渡し)。受け渡される側の配列はnewArray配列宣言しなくてOK。


Roi.getContainedPoints(xpoints,ypoints);		//設定したROIに含まれるすべての座標(x,y)を配列xpointsとypointsに格納する。続いてgetPixel(xpoints[i],ypoints[i])でi番目の座標の信号値も取り出せる。矩形ROI、多角形ROI、円形ROIなんでもOK。iの順番は上側から+y方向にスキャンする感覚。


roiManager("count");		//ROIマネージャーにaddされているROIの数を変数に返す。


roiManager("Delete");		//ROIマネージャーにaddされたROIの中で、選択したROIだけを登録から削除する。Deselectされた状態だと全削除。


roiManager("Add");		//設定したROIをROIマネージャーにadd(登録)する。


roiManager("Deselect");		//ROIマネージャーにaddされたROIの、選択状態を解除する。


roiManager("Select", 数値);		//ROIマネージャーにaddされたROIから、数値で指定した番号のROIを選択する。一覧の一番上は0番。


run("Apply LUT");		//画像の表示信号値・コントラスト(LUT)を、setMinAndMaxで指定した値で変更する。


run("Crop");		//設定したROIでCrop(切り出し)を行う。


run("Duplicate...", "タイトル");		//アクティブなimageを複製して、タイトルと名付ける。


run("Input/Output...", "jpeg=90 gif=-1 file=.csv save_column save_row");		//Input/Outputオプションで、JPRG品質を指定する。この例だと90。


run("Make Binary");		//バイナリ化(二値化)する。閾値はimageJ内のアルゴリズムで自動設定。


run("Size...", "width=1600 average interpolation=Bicubic");		//widthで指定したpixel数にBicubic形式でリサイズする。Heightを省略してるので、width値に応じて等アスペクト比で計算してくれる。


run("Specify...", "width=100 height=100 x=10 y=10");		//Specifyを起動し、ROIの位置、大きさを指定する。


run("Translate...", "x=1 y=1 interpolation=None");		//画像の平行移動。x方向に+1、y方向に+1動く。


saveAs("JPEG",パス);		//パスで指定した位置+ファイル名でJPEG保存する。


saveAs("PNG",パス);		//パスで指定した位置+ファイル名でPNG保存する。


selectWindow("Log");		//ログ画面を選択し、画面一番手前に表示する。


setBackgroundColor(255, 255, 255);		//バックグラウンド色を(255,255,255)=白に設定する。


setBatchMode(false);		//画像表示モード(通常)に戻す。


setBatchMode(true);		//画像非表示モードにする。


setMinAndMax(min, max);		//画像の表示信号値・コントラスト(LUT)を、minとmaxで指定した値で変更する。run("Apply LUT");しない限りデータ上は変更されない。


setPixel(x,y,数値);		//(x,y)のピクセル値を数値で置き換える。


setTool("rectangle");		//長方形ROI設定Toolを選択した状態にする。


showMessage("文章");		//ポップアップに文章を表示する。


showMessageWithCancel("文章");		//ポップアップに文章を表示させ、[OK]をクリックすると命令が続き、[Cancel]をクリックするとマクロを強制終了する。


sqrt(n);		//nの二乗平方根を返す。


substring(文字列,開始する番号);		//対象とする文字列から、「終了番号」以降(終了番号の文字も含む)の文字列を取り出して、変数に返す。先頭の文字は0番目。


substring(文字列,開始する番号,終了する番号);		//対象とする文字列から、「開始番号」〜「終了番号の一つ手前」までの文字列を取り出して、変数に返す。先頭の文字は0番目。


Table.create("タイトル");		//タイトルと名付けたテーブルを作成する。(この後にTable.setするまでにprintなどでLogをアクティブにすると、作成したテーブルと違う新たなテーブルを作ってしまうので注意)


Table.set("列名",行数,数値);		//行数で指定した行(一番上は0)、列名で指定した列に、数値を格納する。Table.update;するまで繰り返して行列を埋める。


Table.update;		//Table.setで埋めたテーブルをアップデートして表示させる。


var 変数;		//変数をグローバル変数(g)にする。マクロ内の関数を含めたマクロ全体で、変数を共有できる。


wait(数値);		//数値msだけ次の命令まで時間を空ける。wait(1000)なら1秒間。


waitForUser("タイトル","文章");		//「タイトル」と名付けたポップアップに文章を表示し、[OK]をクリックするまで命令を一時停止する。この間に画像読み込みやROIの設定など、自由に行える。


配列.length		//配列の要素数(引き出しの数)を返す。


 

 

ImageJの基本操作や、かんたんなマクロの使い方について知りたい方は「ImageJではじめる生物画像解析」という書籍もオススメです。

 

 

分量は多くはないですが、デジタル細胞生物学 データベース化・ImageJ・R・コマンドライン・Gitは、実践的なマクロコードのサンプルを学習するのにオススメ。

 

 

 コードの説明は以下の公式ページでも解説されています。こちらも参考に。

imagej.nih.gov

 

 

 

 

 おしまい

 

 

 

 以下宣伝です!

 

・ImageJ インストール法


・基本処理を凝集した、使い勝手の良い万能系

 

・縦線ノイズ除去のススメ


・公開したマクロのまとめ

imagej-jisui.hatenablog.com