使用OpenCV4Android保存ORB特征向量(java API)

Noh*_*eem 8 storage android opencv vector feature-detection

我有一组训练图像,我已经检测计算了它们的特征向量(使用ORB特征描述符和提取器.问题是:因为我需要保存这些特征以重新使用它们以匹配测试图像(使用SVM分类器); 在Android设备上本地存储特征向量的最佳方法是什么?

要保存的特征向量是每个图像的可变大小,因此具有非最大大小的特征向量用零填充以统一所有向量的大小.目前最大尺寸为500行×32列; 因此16k功能.

这是我到目前为止可以达到的选项;

  • 我听说过OpenCV的FileStorage,但是在浏览java文档时,我注意到了HOG功能的一种save方法(不是ORB).此外,我不确定使用OpenCV的文件存储选项保存功能对于Android手机来说是否是最佳内存方式,因为xml文件太大而无法加载.
  • 我目前的选择是选择一个sqlLite数据库,有一个包含两个cols的表; id和功能(如在线经常建议的那样); 列表sqlLite中的所有16k功能.这似乎是电话存储密集型,但它是我能找到的最合理的解决方案.

有没有一种常用的方法来处理Android手机上的特征向量?它是否包含上述任何方法; 如果没有,请您提供一些有关如何实施此类存储解决方案的指南?

谢谢.

Rui*_*ues 5

在我看来,存储关键点的最通用方法是首先将它们转换为数据交换格式,如JSON.

在您能够进行转换后,您可以灵活地存储它.JSON很容易转换为String和/或通过网络连接发送.

使用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;
}
Run Code Online (Sandbox Code Playgroud)


mor*_*paj 0

我建议将特征向量存储为图像,以获得简单而紧凑的表示。您甚至可以使用非破坏性压缩(例如 png)来最小化文件大小。