ここでは、IMCのバージョン3開発について書きつずって行きます。
2019年12月~
IMCもバージョン1、バージョン2と進んできて、遂にバージョン3の開発になります。
作者であるRedの定年退職が目の前に迫り、IMCバージョン3からは定年退職後の生活費の一部にでもと、有料公開を前提に認証機能を取り込みながら、メモリ使用量抑制と速度向上を目指し、かつ類似画像検出精度向上に取り組みました。
基本的なロジックはバージョン2で出来上がっていますので、上記機能向上を主眼において開発を行いました。
-
- メモリ使用量抑制は、常時は画面に表示しているデータをメモリ上に保持しておき、画像比較時にデータベースから必要なデータを逐次読取ることで実装しましたが、まったく速度が出ません。
そこで、画像比較に最低限必要なAverage HASHデータを事前にデータベースからバイナリーダンプしておき起動時に読込めば、かなりの速度向上が期待出来ますので、実装しました。
バイナリーファイルの読み書きは、今回が初めての経験でした。
Average HASH以外のHASHデータは必要になった都度、データベースから読込ますが、やはりデータベースからの読込は圧倒的に遅いので、一度読みだしたデータをキャッシュしておき、次の読み込み時にキャッシュ上にそのデータが有れば、データベースへ読込に行かないようにしています。キャッシュは単純なFIFO(First In First Out)ですが、キャッシュヒット率95%程度を発揮して、高速化に大いに寄与しています。なお、使用メモリ抑制のため、キャッシュ量は、取り込み済み画像数の10%にしています。
キャッシュロジックの実装も今回が初めての経験でした。 - 類似画像でCPU負荷が上がらない問題については、原因が判明せず解決に苦労をしました。
類似画像検索では、総当たりで画像を比較しています。このため1枚の画像に対して数100万回の比較を、全論理プロセッサに割り当てて実行しているので、全論理プロセッサに割り当てた処理が全て完了しないと次の画像比較に進めません。この論理プロセッサの処理同期を行っているのが、1番スレッドです。この1番スレッドは論理プロセッサの処理同期以外に、画面に進捗を表示するプログレスバーの更新も行っています。もちろん1番スレッドも画像比較を行っています。
プログレスバーの更新は1%の進捗率の変化を反映する様に実装していました。これを10%の進捗率の変化があれば更新する様に変えたところ、CPU負荷が30%から80%へ激増し、類似画像検索の速度が劇的に早くなりました。画面を表示しているフォアグランドスレッドのオブジェクトをバックグラウンドスレッドから直接触れないので、Invoke命令を介して操作するのですが、このInvoke命令が致命的に遅いようです。 - データベースの処理をアプリからデータベースへ
バージョン2までは、データベースの操作はIMCからSQL文を発行して行っていましたが、データベース機を別立てにした場合に、データベース機側へ負荷を移すため、バージョン3からはデータベース側にユーザ定義関数を作り、プログラムからは関数名に引数を付けて呼び出す方式(バインド変数方式)にしています。 - 画像サムネイル作成を、.NetFrameworkからAForgeへ
バージョン2までは、画像取込み時に行っているサムネイル作成とHASH用の16×16ピクセル画像の作成を、.NetFrameworkが提供している関数で行っていましたが、バージョン3からは、AForgeに変えて速度向上させています。これで、画像取込み速度が30%程度早くなりました。 - 類似画像の誤検知抑制
Average HASHは優秀で高速な画像比較法ですが、比較対象が増えれば増えるほど誤検知数が増大します。誤検知率を改善するには新たな画像比較法を実装する必要がありました。
ひらめきました。
そして、2種類の画像比較法を実装しています。
どの様な、アルゴリズムかって! それは企業秘密ということで公開を控えます。
効果のほどは、画像比較で「高精度比較を行う」チェックを外して見てください。
Average HASH法単体と全ての比較エンジンを使った差が理解できると思います。
- メモリ使用量抑制は、常時は画面に表示しているデータをメモリ上に保持しておき、画像比較時にデータベースから必要なデータを逐次読取ることで実装しましたが、まったく速度が出ません。
- ということで、IMC バージョン3.0.0発売です。
それでは、IMCの将来を見て行きましょう。