nigoblog

技術系会社のCEOブログ~私的編~

PHPのGDライブラリを使ってヒストグラムを描画する~ルービックキューブの色を解析~

前回PHPのGDライブラリを使って画像の色を取り出す~ルービックキューブの画像処理~ - nigoblogに引き続きGDライブラリを用いた画像処理プログラムを公開します。

前回
画像処理をするには下処理が重要
ということを書きました。
例えばこの画像のこの部分は○色だ!というような処理をしたい時、予めその処理をしやすいような処理をするということです。

  1. ヒストグラムとは
  2. RGBごとにヒストグラムを作成
  3. 実装
  4. 結果

こんな感じで説明します。

ヒストグラムとは

ヒストグラム(histogram)はざっくりいうと棒グラフのことです。ざっくりいうとってかそのままの気がするけど。。。
棒グラフをかっこ良くいう感じですね。
web系の人間ならABC分析やABテストで用いられるかと思います。
どういう時に用いられるかというと、「ある状態やもの」の「数や売上」などがどれだけあるかということを相対的に知りたい時に用いられます。
今回の場合
ある状態 = RGBそれぞれの階調(16段階)
となり
RGBそれぞれの階調がどれだけあるかということを相対的に知りたい。
ということを叶えるヒストグラムを得ます。

RGBごとにヒストグラムを作成

RGBそれぞれ16段階あるとし、それぞれがどれだけあるかを画素ごとにカウントしていきます。
前回PHPのGDライブラリを使って画像の色を取り出す~ルービックキューブの画像処理~ - nigoblog同様、左上からスキャンしていきます。

実装

それでは実際に実装したものが以下となります。前回のコードの下に入るような感じです。

// 1
$histogramR = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
$histogramG = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
$histogramB = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

// 2
for($y = 0; $y < $imagey;$y++){
	for($x = 0; $x < $imagex; $x++){
		$rgb = imagecolorat($img, $x, $y);
		$r = ($rgb >> 16) & 0xFF;
		$g = ($rgb >> 8) & 0xFF;
		$b = $rgb & 0xFF;
		$histogramR[(int)($r/16)]++;
		$histogramG[(int)($g/16)]++;
		$histogramB[(int)($b/16)]++;	
	}
}
// 3
function writeHistogram($value, $char){
	for($i=0;$i<$value;$i++){
		echo $char;
	}
}
// 4
echo 'Red <br>';
foreach($histogramR as $countR){
	writeHistogram($countR/100, 'r');
	echo '<br>';
}
echo 'Green <br>';
foreach($histogramG as $countG){
	writeHistogram($countG/100, 'g');
	echo '<br>';
}
echo 'Blue <br>';
foreach($histogramB as $countB){
	writeHistogram($countB/100, 'b');
	echo '<br>';
}

まず1はヒストグラムのデータの初期値を設定します。
2で画像をスキャンし、画素ごとにRGBの値を取り出します。それを16で割ることで階調を16段階にします。もう少し細かく分けたければ10で割ると26段階、8で割ると32段階とどんどん階調を増やすことができます。
3の関数はヒストグラムを描画する関数で、4で実際に描画します。数を100で割っているのは数が大きすぎたためです。

結果

それでは上記の結果を示します。まず、用いた画像は次の画像です。
f:id:nigohiroki:20121016002649p:plain

それのヒストグラムを作成した結果次のようになりました。上から順に0 ~ 15までの16段階のヒストグラムです。

Red 
0~15       rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
16~31     rrrrrrrrrrrrrrrrrrrrrr
32~47     rrrrrr
48~63     rrrr
64~79     rrr
80~95     rrr
96~111   rrr
112~127 rr
128~143 rrrrr
144~159 rrrrrrr
160~175 rrrrrrrrrrrr
176~191 rrrrrrrrrrrrrrr
192~207 rrrrrrrrrrrrrr
208~223 rrrrrrrrrrrrrrrrr
224~239 rrrrrrrrrrrrrr
240~255 rrrr

軸がないのがわかりにくいので後で付け足しました。このヒストグラムからわかることは全体的に暗いということ。また144~239の間にも分布していることが一目でわかります。

まとめ

結果からわかることは、47以下の階調の場合、階調に比例した数をかけることでうまく処理ができるかと考えられます。
下処理をどうするかはまだわかりませんが、とりあえず今回は下処理をするための下処理ということでした。

それ以外にもヒストグラムの考え方がなんとなくわかったかと思います。

それではルービックキューブアプリ乞うご期待!!