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

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

【ImageJマクロ超入門】#8 二次元画像のピクセル値を取得する方法

 

f:id:yu3xx:20210515005743j:plain


 

皆さまこんにちは。

いまだに「戦国サイバー 藤丸地獄変」で遊んでいます、yu3xx(ゆーさんちょめちょめ)です。

 

 

前回のおさらい



前回はROIを使った画像解析についてまとめました。


今回は「画像から直接ピクセル値を拾ってきて、画像処理や解析をする方法」です。

 

二次元画像の解析では基本となる処理の一つだと思います。


漫画自炊でも「縦線ノイズ除去マクロ」で使っている処理です。

 

 

もくじ

 

 

ピクセル値の取得と置き換え


ピクセル値取得の命令

 value = getPixel(x, y);

座標(x,y)のピクセル値を変数valueに格納します。


ピクセル値の置き換え

 setPixel(x, y, newValue);
座標(x,y)のピクセル値を変数newValueの値で置き換えます。


それではこの2つの命令を使って、8bitグレースケール画像を白黒反転させる処理を作ってみましょう!

 

サンプル1(白黒反転)


あらかじめ好きな画像を開いておいてください。

 

使いやすい画像を持っていない方は、定番のLennaさん画像をwikipediaからダウンロードして使ってください。

f:id:yu3xx:20210515011002j:plain

File:Lenna (test image).png - Wikipedia


画像は画像ファイルを「ImageJのメインウィンドウ」に「ドラッグ&ドロップで開くことが出来ます。

 


//example 8-1

//あらかじめ画像を開いておく


//画像をグレースケール8bitに置き換え
run("8-bit");

//画像のタテとヨコのpixel数を取得
w = getWidth();
h = getHeight();

//座標xとyで二重ループ
for(x=0; x<w; x++){
	for(y=0; y<h; y++){
		//オリジナルのpixel値取得
		originalValue = getPixel(x, y);
	
		//Max値255からオリジナルpixel値を引く
		newValue = 255 - originalValue;
		
		//新しいpixel値で置き換え
		setPixel(x, y, newValue);
	}
}

 
二次元画像の解析では、xとyを二重でループさせることで全画素に対して順次処理を行います。


これが今回のポイントの一つです。


基本的にはxとyのどちらを先に書いてもOKですが、どちらを先に書くかで「画素チェックの走査方向」が変わります

 

これを意識しておくことは、複雑な処理・解析をするときに重要となってきます。

 

サンプルコードではx固定で先にyループを回し、その後xを1つ大きくしてまたyループを回し...となるので、下図のような走査方向になります。

f:id:yu3xx:20210515011227j:plain

 

 

8bitグレースケールは256階調、最小値0、最大値255なので、255からオリジナルの値を引き算することで白黒反転できます。

 

f:id:yu3xx:20210515010938j:plain

白黒反転するとこうなるはずです。

 

自作関数による画像解析


二次元画像の扱い方がわかったところで、自作関数(ユーザー定義関数)を使って簡単な画像解析をしてみます。

 

自作関数の基礎解説は以下のリンクから。

 

今回は「ある値よりも大きなピクセル値を持つ画素の数をカウントする」という解析をしてみます。

 

サンプル2(条件を満たす画素のカウント)


閾値(threshold)とするピクセル値を、変数thとして設定。


//example 8-2

//あらかじめ画像を開いておく

run("8-bit");

a = countPixel(10);
print(a);

a = countPixel(128);
print(a);

a = countPixel(200);
print(a);


//-----------------------------------------------------------------------------

function countPixel(th){
	w = getWidth();
	h = getHeight();
	
	//countを初期化
	count = 0;

	for(y=0; y<h; y++){
		for(x=0; x<w; x++){
			pixelValue = getPixel(x, y);

			//閾値thよりも大きなpixel値のときだけカウントアップ
			if(pixelValue > th){
				count++;
			}
		}
	}
	return count;
}

//-----------------------------------------------------------------------------

 
実行すると、値が10以上の画素数、値が128以上の画素数、値が200以上の画素数が表示されます。

f:id:yu3xx:20210515012506p:plain
これが画素カウントを数える命令のテンプレです。

 

ifの条件を変えることで、「○○以上××未満」のような指定も出来ます。

 

 

 

今回は以上です。


getPixelやsetPixelを使えるようになると、解析や処理の幅がかなり拡がると思います。

 

 

ちなみに今回の内容は「8bitグレースケール画像」を対象にした解説でした。

もしも「32bitカラーRGB画像」を対象とする場合はちょっと工夫が必要なので、気になる方は下のリンクからどうぞ。


 

 

今回の要点はこんな感じです。

 

ピクセル値の取得はvalue = getPixel(x,y)」

ピクセル値の置換は「setPixel(x,y,value)」

・二次元画像の走査はxとyの二重ループ

 

 

次回は、処理・解析を快適にしてくれる「情報入力ダイアログの作り方」を紹介します!

imagej-jisui.hatenablog.com

 

 


おしまい

 

 

 

 

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

imagej-jisui.hatenablog.com