作業計画
- 歪みのある低品質の画像でヒーローのアイコンを認識します。
- 選択したヒーローの分析を実行し、各チームに適した組み合わせを選択します。
- 結果を表示します。
まず、x86アプリケーション(C ++ / OpenCV)を開発し、後で実際のカメラでAndroidに移植することにしました。 必要だったのは、高速で正確な画像比較アルゴリズムです。 長い検索の後、最も一般的なアプローチが明らかになりました。
- 単純なユークリッド距離
- 相互相関
- ヒストグラム比較
- 顕著なポイント/エリアの検出器
他のオプションは複雑すぎるか、OpenCVに実装されていないため破棄されます。
実験中に、最初にヒーローの輪郭を認識し、そのヒーローのコンテンツを元のアイコンと比較する必要があることが明らかになりました。 テンプレートマッチングを使用して大きなスクリーンショットで小さなアイコンを検索すると、非常に時間がかかります。 動作原理は次のとおりです。
- アイコンのバイナリマスクを準備する
- アウトラインを見つける
- 誤検知を除外する
- 認識ストリームを実行する
元の画像:
マスク:
ヒーローの概要:
私は、輪郭の認識を多く処理し、マスクと偽陽性のフィルターの最適なパラメーターを調整する必要がありました。 画像の品質が低いか、歪みがあり、モニターごとに比率が異なる場合があります。
アイコンを認識するために、初期フィルタリング用のcv :: matchTemplateと正確な比較用のcv :: FlannBasedMatcherを組み合わせたクールなバイクが作成されました。 これらの係数に基づいて、類似性の重みが計算され、最大の重みを持つヒーローが返されました。
長い間、似たようなアイコンを比較する問題に苦労していましたが、最終的には得点しました。 まれにしか発生しません。 たとえば、入力画像AはヒーローCとして認識されます。
合計で、認識結果によると、エラーは約10%で、Core i5の1フレームは最大200ミリ秒、Nexus7では最大2秒で計算されます。 確かに多くのことを最適化できますが、プロトタイプには十分でした。
アプリケーションの主な機能は準備が整っており、Androidに移植し、カメラのサポートを追加して結果を表示するために残りました。 ここでは、アプリケーションに費やした時間の約70%がさまざまなデバイスでのAndroidのバグとの戦いに費やされていたので、非常に間違っていました。
カメラAPIに特に満足しています。 フォーカス制御、ファインダーのビデオと写真の解像度-これらはすべて、完全にフリーズするまで問題を引き起こす可能性があります。 予算の少ない中国の携帯電話でテストして、最大限のバグをキャッチすることをお勧めします。
JNIは苦痛であることに言及する価値があります。 そこで、データをByteBufferに転送することにしました。 はい、SWIGのようなあらゆる種類のジェネレーターがありますが、それらは非常に大きく、排気コードは怖いです。
apkサイズの最適化に関する小さなヒント。 すべてのネイティブコードを1つの共有ライブラリに収集し、余分なものを削除した結果、合計サイズが3倍に削減されました。
CFLAGS:= -DANDROID_NDK -DNDEBUG -O3 -Ofast -flto -fvisibility = hidden -ffunction-sections -fdata-sections
LDFLAGS:= -Wl、-gc-sections -Wl、-exclude-libs = ALL