本文介绍了如何在 Java 中加载使用 FileStorage 保存的 OpenCV 矩阵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In C++, OpenCV has a nice FileStorage class that makes saving and loading Mat a breeze.

就这么简单

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

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

文件格式为 YAML.

The file format is YAML.

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

I want to use a Mat that I create with a C++ program in Java, ideally, loading it from the saved YAML file. However, I cannot find an equivalent class to FileStorage in the Java bindings. Does one exist? If not, what alternatives do I have?

推荐答案

一种可能的解决方案是使用诸如 yamlbeanssnakeyaml.

One possible solution is to write a YAML parser using a Java library such as yamlbeans or snakeyaml.

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

I choose to use yamlbeans because the default FileStorage encoding is YAML 1.0, and snakeyaml requires 1.1.

我的 C++ 代码

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

保存以下示例 YAML 文件

Saves the following example YAML file

%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"后,我可以使用

After I remove the header, "%YAML:1.0", I can load it into Java using

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;
    }
}

这篇关于如何在 Java 中加载使用 FileStorage 保存的 OpenCV 矩阵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 21:25