shunji のすべての投稿

PHPでカラーヒストグラム

あるお仕事で類似画像検索を行うことになりました。

こちらがとても参考になりました。

が、PHPじゃなかったので、PHPで書いてみました。

 

類似画像検索のために、

画像からカラーヒストグラム(64色)を作成して、

DB(MySQL)に登録することにしました。

 

まずは、関数を作っておいて

 

// オリジナル画像のRGBからヒストグラムのビン番号を計算

function rgb2bin($red, $green, $blue) {

$redNo = (int)($red / 64);

$greenNo = (int)($green / 64);

$blueNo = (int)($blue / 64);

return 16 * $redNo + 4 * $greenNo + $blueNo;

}

 

以下、メイン処理

 

// 画像ファイルを読込み&画像サイズ取得

$filepath = ‘img/hoge.jpg';

$img = imagecreatefromjpeg($filepath);

$width= imagesx($img);

$height= imagesy($img);

 

// カラーヒストグラムを生成

$histogram = array();

for ($i = 0; $i < 64; $i++) {

$histogram[$i] = 0;

}

 

for($y = 0; $y < $width; $y++){

for($x = 0; $x < $height; $x++){

$rgb = imagecolorat($img, $x, $y);

$r = ($rgb >> 16) & 0xFF;

$g = ($rgb >> 8 ) & 0xFF;

$b = $rgb & 0xFF;

$bin = rgb2bin($r, $g, $b);

$histogram[$bin] += 1;

}

}

imagedestroy($img);

 

// ヒストグラムを全体を1になるように正規化

for ($i = 0; $i < 64; $i++) {

$histogram[$i] = $histogram[$i] / ($width* $height);

}

 

これで $histogram 配列にヒストグラムが入ったので、

後は、それら 64 つの値を、そのままDBに登録するだけです。

(登録処理は省略)

 

DBに入ったら、やっと類似検索ができます。

以下のSQLでは、検索元となる画像のヒストグラムと

その画像も含めた全てのヒストグラムをクロスジョインして

類似度(Histogram Intersection)を計算し、

類似度の降順で結果を返しています。

 

select a.id as a_id, b.id as b_id,

truncate(LEAST(a.bin_00, b.bin_00) + LEAST(a.bin_01, b.bin_01) + LEAST(a.bin_02, b.bin_02) + LEAST(a.bin_03, b.bin_03) + LEAST(a.bin_04, b.bin_04) + LEAST(a.bin_05, b.bin_05) + LEAST(a.bin_06, b.bin_06) + LEAST(a.bin_07, b.bin_07) + LEAST(a.bin_08, b.bin_08) + LEAST(a.bin_09, b.bin_09) + LEAST(a.bin_10, b.bin_10) + LEAST(a.bin_11, b.bin_11) + LEAST(a.bin_12, b.bin_12) + LEAST(a.bin_13, b.bin_13) + LEAST(a.bin_14, b.bin_14) + LEAST(a.bin_15, b.bin_15) + LEAST(a.bin_16, b.bin_16) + LEAST(a.bin_17, b.bin_17) + LEAST(a.bin_18, b.bin_18) + LEAST(a.bin_19, b.bin_19) + LEAST(a.bin_20, b.bin_20) + LEAST(a.bin_21, b.bin_21) + LEAST(a.bin_22, b.bin_22) + LEAST(a.bin_23, b.bin_23) + LEAST(a.bin_24, b.bin_24) + LEAST(a.bin_25, b.bin_25) + LEAST(a.bin_26, b.bin_26) + LEAST(a.bin_27, b.bin_27) + LEAST(a.bin_28, b.bin_28) + LEAST(a.bin_29, b.bin_29) + LEAST(a.bin_30, b.bin_30) + LEAST(a.bin_31, b.bin_31) + LEAST(a.bin_32, b.bin_32) + LEAST(a.bin_33, b.bin_33) + LEAST(a.bin_34, b.bin_34) + LEAST(a.bin_35, b.bin_35) + LEAST(a.bin_36, b.bin_36) + LEAST(a.bin_37, b.bin_37) + LEAST(a.bin_38, b.bin_38) + LEAST(a.bin_39, b.bin_39) + LEAST(a.bin_40, b.bin_40) + LEAST(a.bin_41, b.bin_41) + LEAST(a.bin_42, b.bin_42) + LEAST(a.bin_43, b.bin_43) + LEAST(a.bin_44, b.bin_44) + LEAST(a.bin_45, b.bin_45) + LEAST(a.bin_46, b.bin_46) + LEAST(a.bin_47, b.bin_47) + LEAST(a.bin_48, b.bin_48) + LEAST(a.bin_49, b.bin_49) + LEAST(a.bin_50, b.bin_50) + LEAST(a.bin_51, b.bin_51) + LEAST(a.bin_52, b.bin_52) + LEAST(a.bin_53, b.bin_53) + LEAST(a.bin_54, b.bin_54) + LEAST(a.bin_55, b.bin_55) + LEAST(a.bin_56, b.bin_56) + LEAST(a.bin_57, b.bin_57) + LEAST(a.bin_58, b.bin_58) + LEAST(a.bin_59, b.bin_59) + LEAST(a.bin_60, b.bin_60) + LEAST(a.bin_61, b.bin_61) + LEAST(a.bin_62, b.bin_62) + LEAST(a.bin_63, b.bin_63) + 0.005, 2) as intersection

from color_histogram as a

cross join color_histogram as b

where (a.id = ‘hogehoge’) order by intersection desc;

 

同じ画像の場合は類似度は1になります。

1に近いほど似ていて、0に近いほど似ていません。

このSQLで類似度が出せるのは、

事前にヒストグラムの合計値が1になるように正規化しているためです。

 

まだまだ、試作段階で、

件数が多くなったときの速度が非常に心配ですが、

今のところはこんな感じです。

Bootstrap を使ってみた。

遅ればせながら、Bootstrap を使ってページを作成してみました。

Bootstrap とは、Webページを簡単に作成できるCSSフレームワークとよばれるツールの1つです。

簡単にといいましたが、HTML と CSS の知識は必要です。

 

本家のサイトはこちら

http://getbootstrap.com/

ここからダウンロードした CSS ファイルを

HTMLに読む込むだけで、すぐに使えます。

 

使ってみた感想としては、

デザイン力が無くても、それなりに統一感のあるページができちゃうところが素晴らしい。

さらには、グリッドシステムにより、レスポンシブWebデザインも

簡単にできちゃうところが素晴らしいです。

 

ちなみに、ダイアログには Bootbox を使いました。

これでさらに統一感が増しました。

 

デザインに細かい指定がない時などに使えると思います。

使ったことのない方は、使ってみてはいかがでしょうか。

(もっと早く知ってればよかった、、、)

ドローン

最近、ドローンという言葉をよく目にします。

ここでいうドローンとは、無人飛行機(Drone)のことです。

 

スマホで飛ばす「小型ドローン」が1万2800円で–走行型ロボットも

私が子供のころに流行っていたミニ四駆と比べると、、、、

相当なハイテクっぷりです。

 

アマゾンの「ドローン配達」が実現に向けて一歩前進

空から荷物が届きます!!

映画の世界が、もう数年後には当たり前になっているかもしれません。

 

とってもわくわくしますね。

生きているうちに、どこまで進むのでしょう。

エンジニアとして、少しでもみんなをわくわくさせる仕事が出来ればいいなぁ

と感じた今日この頃でした。

世界は広いよね

プログラミングでつまづいた時、日本語のサイトに解決方法が見つからなければ、

英語のサイトまで検索範囲を広げて解決策を求めますが、

英語が苦手な私としては、英語の記事を進んで読む、ということがありません。

 

そんな私が最近見つけたサイト

POSTD – 海外の最新テクノロジー系ニュースを日本語で

 

このサイトでいろいろと記事を読んでいると、

世界は広い!!と実感しました。いろんな方がいるなぁと。

逆に自分がいかに狭い世界で生きていたのかも。

 

技術者として英語が読めるぐらいはできたほうがいいと思います。

私のように英語に苦手意識のある方、

その入り口として、まずは世界をのぞいてみることから

初めてみてはどうでしょう?