Speichern von ORB-Feature-Vektoren mit OpenCV4Android (Java-API)

8

Ich habe einen Trainingssatz mit Bildern, für die ich jeweils erkannt und berechnet ihre Feature-Vektoren (mit ORB-Feature-Deskriptoren und Extraktoren. Die Frage ist : da ich diese Features speichern muss, um sie mit Testbildern abzugleichen (unter Verwendung des SVM-Klassifikators); Wie kann man die Feature-Vektoren am besten lokal auf dem Android-Gerät speichern?

Die zu speichernden Merkmalsvektoren haben eine variable Größe pro Bild, und daher werden diejenigen mit nicht-maximalen Größen mit Nullen aufgefüllt, um die Größe aller Vektoren zu vereinheitlichen. Die maximale Größe beträgt derzeit 500 Zeilen x 32 Spalten; also 16k Features.

Hier sind die Optionen, die ich bisher erreichen konnte;

  • Ich habe von OpenCVs FileStorage gehört, aber wenn es losgeht Durch die Java-Dokumentation habe ich eine save -Methode für HOG-Funktionen (nicht ORB) Außerdem bin ich mir nicht sicher, ob das Speichern von Features mit den OpenCV-Dateispeicheroptionen für Android-Telefone optimal ist, da die XML-Datei zum Laden zu groß ist.
  • Meine aktuelle Wahl ist, sich für eine sqlLite-Datenbank zu entscheiden, die eine Tabelle mit zwei Spalten hat; ID und Funktion (wie häufig online vorgeschlagen); um alle 16k Features in sqlLite zu tabellieren. Das scheint eher ein Telefonspeicher zu sein, aber es ist die vernünftigste Lösung, die ich finden kann.

Gibt es eine übliche Methode, um Feature-Vektoren auf Android-Telefonen zu handhaben? Umfasst es eine der oben genannten Methoden? Wenn nicht, können Sie bitte einige Richtlinien zur Implementierung einer solchen Speicherlösung geben?

Danke.

    
Noha Kareem 07.03.2013, 12:35
quelle

3 Antworten

5

Meiner Meinung nach besteht die universellste Art, die Schlüsselpunkte zu speichern, darin, sie zuerst in ein Datenaustauschformat wie JSON zu konvertieren.

Nachdem Sie diese Konvertierung durchführen können, haben Sie viel Flexibilität, um sie zu speichern. JSON kann einfach in einen String konvertiert und / oder über eine Netzwerkverbindung gesendet werden.

Mit OpenCV C ++ können Sie Daten speichern als YAML , aber das ist noch nicht für Android verfügbar.

Um JSON in Java zu parsen, können Sie diese einfach zu verwendende Bibliothek Google GSON verwenden.

Und hier ist mein erster Versuch, genau das zu tun:

%Vor%     
Rui Marques 21.02.2014 00:39
quelle
0

Ich würde vorschlagen, die Merkmalsvektoren als Bilder zu speichern, um eine einfache und kompakte Darstellung zu haben. Sie können sogar eine nicht-destruktive Komprimierung wie png verwenden, um die Dateigröße zu minimieren.

    
morotspaj 31.12.2013 12:43
quelle
0

Ich sehe, dass Sie die Android SQLite-Datenbank in Betracht gezogen haben:

  

Meine aktuelle Wahl ist, sich für eine sqlLite-Datenbank zu entscheiden, die eine Tabelle mit zwei Spalten hat; ID und Funktion (wie häufig online vorgeschlagen); um alle 16k Features in sqlLite zu tabellieren. Das scheint eher telefonspeicherintensiv zu sein, aber es ist die vernünftigste Lösung, die ich finden kann.

There ist eine Möglichkeit zum Speichern und Abrufen von MatOfKeyPoint in SQLite-Datenbank mit angemessener Effizienz.

Die Verwendung der Datenbank hat den Vorteil, dass Sie nicht die Berechtigung zum Schreiben externer Speicher von dem Benutzer anfordern müssen (obwohl diese Berechtigung für einige andere Ihrer Apps-Funktionen erforderlich sein könnte).

Es gibt eine vollständige Android-Lösung mit Java-Code, die in dieser StackOverflow-Antwort gefunden werden kann.

Das Folgende ist eine Beschreibung dessen, was in dem Code von dieser Antwort aus vorgeht ...

MatOfKeyPoint zu Byte [] und einige Attribute

Um in der Datenbank zu speichern, müssen Sie in einem byte[] -Objekt speichern. Mit der MatOfKeyPoint.get() -Methode können Sie einen bevölkerten float[] erhalten. Mit ByteBuffer.putFloat() können Sie dann alle Floats durchlaufen und schließlich mit byte[] einen bevölkerten ByteBuffer.array() erhalten.

Sie müssen außerdem einige Attribute MatOfKeyPoint.rows() , MatOfKeyPoint.cols() und MatOfKeyPoint.type() zusammen mit blob von byte[] in Ihrer Datenbank speichern.

Datenbank-Blob (byte []) zu MatOfKeyPoint

Um Ihr MatOfKeyPoint -Objekt aus der Datenbank wiederherzustellen, machen Sie zuerst einen float[] aus Ihrem Blob. Verwenden Sie ByteBuffer.wrap(blob) , führen Sie dann ByteBuffer.asFloatBuffer() und schließlich FloatBuffer.get() mit einem korrekt großen neuen float[] aus.

Nun, da Sie yourFloatArray haben, führen Sie MatOfKeyPoint.create(rows, cols, type) aus, diese drei Dinge, die aus dem Datenbankdatensatz kommen. Schließlich führen Sie MatOfKeyPoint.put(0, 0, yourFloatArray) .

    
Dale 23.05.2017 14:38
quelle