JavaCV を使用して 三国志大戦4 解任済み武将カード の 武将 を 特徴点 から判定する(失敗)

kameyatakefumi.hatenablog.com

前回、リストから1単位の武将データを抽出する事ができた。
今回、そこから武将を判定したい。

テキストである武将名は読み取りが難しいうえに、蜀の劉備、漢の劉備、レアリティが違う劉備、性能が一緒だけど絵柄が劉備など違うパターンがありぎすて正解を得るのに考慮する事が多すぎる。
絵柄は重複する事がないので、絵柄から武将を判定する。

テンプレートマッチングでやってみても、うまく判定されない。
どうやら画像サイズが違うと判定されないみたいね。

色々調べてみると特徴点でマッチングする手法を知りました。

以下、色んなサイトを見て作成。

public class PointMatching {

    public static void main(String[] args) {

        Mat mat1 = imread("{1単位の武将データの画像}");
        Mat mat2 = imread("{武将の画像}");

        // 特徴点抽出
        KeyPointVector keyPointVector1 = new KeyPointVector();
        KeyPointVector keyPointVector2 = new KeyPointVector();
        ORB orb = ORB.create();
        orb.detect(mat1, keyPointVector1);
        orb.detect(mat2, keyPointVector2);

        // 特徴記述
        Mat matDescriptor1 = new Mat();
        Mat matDescriptor2 = new Mat();
        orb.compute(mat1, keyPointVector1, matDescriptor1);
        orb.compute(mat2, keyPointVector2, matDescriptor2);

        // 特徴点マッチング
        DMatchVector vector = new DMatchVector();
        DescriptorMatcher matcher = DescriptorMatcher.create("BruteForce-Hamming");
        matcher.match(matDescriptor1, matDescriptor2, vector);

        // 結果作成
        Mat result = new Mat();
        drawMatches(mat1, keyPointVector1, mat2, keyPointVector2, vector, result);

        imshow("Resutl", result);
        waitKey(0);
        destroyAllWindows();
    }

}

以下、実行結果です。
f:id:kameya_takefumi:20171102172801j:plain
左の画像と右の画像の 特徴点 を線でつなげています。

うーん、ぜんぜんダメやん。
しきい値を設定して 特徴点 を選別しても大して変わりません。
大きい画像を用意しておけば空気を読んでマッチングしてくれるやろっと甘い考えでした。

特徴点マッチングの難しい所は特徴点がどこまで一致していたら同じと判定するかですね。
うーん、向いていない事をやっている感があります。

これなら大きめの画像を用意しておいて、比較する画像に合わせて縮小させてパターンマッチングするほうが楽で正確でしょうね。
比較しあう画像を同サイズにするって、パターンマッチングにおいては最適化しているといえますね。
一見、画像を縮小すると情報が抜け落ちている感覚ですが、不要な情報を削っているといえるのかな。

次はテンプレートとなる大きめの武将カードを用意しておいて、リストから抽出した1単位の画像サイズに合わせて縮小処理をしてパターンマッチングしてみるだな。