【问题标题】:How to load OpenCV Matrices saved with FileStorage in Java?如何在 Java 中加载使用 FileStorage 保存的 OpenCV 矩阵?
【发布时间】:2015-12-15 19:24:41
【问题描述】:

在 C++ 中,OpenCV 有一个很好的 FileStorage 类,它使保存和加载 Mat 变得轻而易举。

就这么简单

//To save
FileStorage fs(outputFile, FileStorage::WRITE);
fs << "variable_name" << variable;

//To load
FileStorage fs(outputFile, FileStorage::READ);
fs["variable_name"] >> variable;

文件格式为 YAML。

我想使用我用 Java 中的 C++ 程序创建的 Mat,理想情况下,从保存的 YAML 文件中加载它。但是,我在 Java 绑定中找不到与 FileStorage 等效的类。一个存在吗?如果没有,我有什么选择?

【问题讨论】:

    标签: java yaml opencv3.0


    【解决方案1】:

    一种可能的解决方案是使用 Java 库(例如 yamlbeanssnakeyaml)编写 YAML 解析器。

    我选择使用 yamlbeans 是因为默认的 FileStorage 编码是 YAML 1.0,而 snakeyaml 需要 1.1。

    我的 C++ 代码

    FileStorage fs(path, FileStorage::WRITE);
    fs << "M" << variable;
    

    保存以下示例 YAML 文件

    %YAML:1.0
    codebook: !!opencv-matrix
       rows: 1
       cols: 3
       dt: f
       data: [ 1.03692314e+02, 1.82692322e+02, 8.46153831e+00 ]
    

    删除标题“%YAML:1.0”后,我可以使用将其加载到 Java 中

    import java.io.FileReader;
    import java.io.FileNotFoundException;
    import java.util.List;
    import java.util.Map;
    import java.util.Scanner;
    
    import org.opencv.core.CvType;
    import org.opencv.core.Mat;
    
    import net.sourceforge.yamlbeans.YamlException;
    import net.sourceforge.yamlbeans.YamlReader;
    
    public class YamlMatLoader {
        // This nested class specifies the expected variables in the file
        // Mat cannot be used directly because it lacks rows and cols variables
        protected static class MatStorage {
            public int rows;
            public int cols;
            public String dt;
            public List<String> data;
    
            // The empty constructor is required by YamlReader
            public MatStorage() {
            }
    
            public double[] getData() {
                double[] dataOut = new double[data.size()];
                for (int i = 0; i < dataOut.length; i++) {
                    dataOut[i] = Double.parseDouble(data.get(i));
                }
    
                return dataOut;
            }
        }
    
        // Loading function
        private Mat getMatYml(String path) {
            try {  
                YamlReader reader = new YamlReader(new FileReader(path));
    
                // Set the tag "opencv-matrix" to process as MatStorage
                // I'm not sure why the tag is parsed as
                // "tag:yaml.org,2002:opencv-matrix"
                // rather than "opencv-matrix", but I determined this value by
                // debugging
                reader.getConfig().setClassTag("tag:yaml.org,2002:opencv-matrix", MatStorage.class);
    
                // Read the string
                Map map = (Map) reader.read();
    
                // In file, the variable name for the Mat is "M"
                MatStorage data = (MatStorage) map.get("M");
    
                // Create a new Mat to hold the extracted data
                Mat m = new Mat(data.rows, data.cols, CvType.CV_32FC1);
                m.put(0, 0, data.getData());
                return m;
            } catch (FileNotFoundException | YamlException e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    【讨论】:

    • 这项工作很好,但在Map map = (Map) reader.read();上很慢
    • @Cecilia 我知道你的答案是 5 岁,但我遇到了类似的问题。我已将您的建议 (+1) 作为起点。我想知道您是否同时遇到了不同的解决方案?你可以看到我对它的扭曲here
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    • 2010-12-14
    • 2022-01-15
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多