8

画像のトレーニング セットがあり、それぞれの特徴ベクトルを検出して計算しました (ORB 特徴記述子とエクストラクタを使用)。問題は、これらの特徴を保存して、テスト画像との照合に再利用する必要があるためです ( SVM 分類器); Android デバイスでローカルに特徴ベクトルを保存する最良の方法は何ですか?

保存される特徴ベクトルは、画像ごとに可変サイズであるため、最大サイズでないものは、すべてのベクトルのサイズを統一するためにゼロでパディングされます。現在の最大サイズは 500 行 x 32 列です。したがって、16k 機能です。

これまでに到達できたオプションは次のとおりです。

  • OpenCV のFileStorageについては聞いたことがありますが、Java のドキュメントを調べていると、 HOG 機能(ORB ではない)のsaveメソッドに気付きました。さらに、xml ファイルが大きすぎて読み込めないことを考えると、OpenCV のファイル ストレージ オプションを使用して機能を保存することが、Android スマートフォンのメモリの観点から最適であるかどうかはわかりません。
  • 私の現在の選択は、2 つの列を持つテーブルを持つ sqlLite データベースを選択することです。ID と機能 (オンラインで頻繁に提案されているもの); sqlLite のすべての 16k 機能を表にします。これはかなり電話のストレージを集中的に使用するように思えますが、私が見つけることができる最も合理的な解決策です。

Android フォンで特徴ベクトルを処理する一般的な方法はありますか? 上記の方法のいずれかが含まれていますか?そうでない場合は、そのようなストレージ ソリューションの実装方法に関するガイドラインを教えてください。

ありがとうございました。

4

3 に答える 3

5

私の意見では、キーポイントを格納する最も一般的な方法は、最初にキーポイントを JSON のようなデータ交換形式に変換することです。

その変換を行うことができた後は、それを保存するための多くの柔軟性があります。JSON は簡単に文字列に変換したり、ネットワーク接続を介して送信したりできます。

OpenCV C++を使用すると、データを YAML として保存できますが、Android ではまだ利用できません。

Java で JSON を解析するには、この使いやすいライブラリ Google GSONを使用できます。

そして、これがまさにそれを行う最初の試みです:

 public static String keypointsToJson(MatOfKeyPoint mat){
    if(mat!=null && !mat.empty()){          
        Gson gson = new Gson();

        JsonArray jsonArr = new JsonArray();            

        KeyPoint[] array = mat.toArray();
        for(int i=0; i<array.length; i++){
            KeyPoint kp = array[i];

            JsonObject obj = new JsonObject();

            obj.addProperty("class_id", kp.class_id); 
            obj.addProperty("x",        kp.pt.x);
            obj.addProperty("y",        kp.pt.y);
            obj.addProperty("size",     kp.size);
            obj.addProperty("angle",    kp.angle);                          
            obj.addProperty("octave",   kp.octave);
            obj.addProperty("response", kp.response);

            jsonArr.add(obj);               
        }

        String json = gson.toJson(jsonArr);         

        return json;
    }
    return "{}";
}

public static MatOfKeyPoint keypointsFromJson(String json){
    MatOfKeyPoint result = new MatOfKeyPoint();

    JsonParser parser = new JsonParser();
    JsonArray jsonArr = parser.parse(json).getAsJsonArray();        

    int size = jsonArr.size();

    KeyPoint[] kpArray = new KeyPoint[size];

    for(int i=0; i<size; i++){
        KeyPoint kp = new KeyPoint(); 

        JsonObject obj = (JsonObject) jsonArr.get(i);

        Point point = new Point( 
                obj.get("x").getAsDouble(), 
                obj.get("y").getAsDouble() 
        );          

        kp.pt       = point;
        kp.class_id = obj.get("class_id").getAsInt();
        kp.size     =     obj.get("size").getAsFloat();
        kp.angle    =    obj.get("angle").getAsFloat();
        kp.octave   =   obj.get("octave").getAsInt();
        kp.response = obj.get("response").getAsFloat();

        kpArray[i] = kp;
    }

    result.fromArray(kpArray);

    return result;
}
于 2014-02-21T00:39:37.393 に答える
0

シンプルでコンパクトな表現を持つために、特徴ベクトルを画像として保存することをお勧めします。png などの非破壊的な圧縮を使用して、ファイル サイズを最小化することもできます。

于 2013-12-31T12:43:14.873 に答える