在 FileStorage 中使用路径作为键

Posted

技术标签:

【中文标题】在 FileStorage 中使用路径作为键【英文标题】:Use path as key in FileStorage 【发布时间】:2017-04-16 22:48:43 【问题描述】:

我正在尝试编写一个文件(json/yaml/xml,格式无关紧要),该文件存储具有特定cv::Mat 的文件路径。当我最终意识到here 时,组合键不允许路径(例如/home/user)。

void
persist_histograms(const QString& filepath, const QHash<QString, Mat>& histograms)

    cv::FileStorage storage(filepath.toStdString(), cv::FileStorage::WRITE);

    QHashIterator<QString, Mat> it(histograms);

    while (it.hasNext()) 
        it.next();
        storage << it.key().toStdString() << it.value();
    

这是cv::FileStorageclass 的真正限制吗?或者有没有办法绕过它?

最终结果应该是这样的:


    "/my/path/to/file.png": "<my cv::Mat serialization here>",
    "/my/path/to/another/file.png": "<my cv::Mat serialization here>",
    ...

观察

错误的发生与格式无关。如果我通过filepath 那 以 yaml/json/xml 结尾,错误是相同的: 如果尝试在键的开头添加一个字母,则会出现以下错误:

这是我在尝试上面的代码时遇到的错误:

OpenCV Error: Unspecified error (Incorrect element name /home/user/dtd/images/freckled/freckled_0055.jpg) in operator<<, file /build/opencv/src/opencv-3.2.0/modules/core/src/persistence.cpp, line 6877
terminate called after throwing an instance of 'cv::Exception'
what():  /build/opencv/src/opencv 3.2.0/modules/core/src/persistence.cpp:6877: error: (-2) Incorrect element name /home/user/dtd/images/freckled/freckled_0055.jpg in function operator<<

如果我尝试在键的开头添加一个字母,这就是我得到的错误。

OpenCV Error: Bad argument (Key names may only contain alphanumeric characters [a-zA-Z0-9], '-', '_' and ' ') in icvJSONWrite, file /build/opencv/src/opencv-3.2.0/modules/core/src/persistence.cpp, line 3896

【问题讨论】:

【参考方案1】:

我好像遇到过类似的错误。如果我尝试像这样以YAML 格式存储矩阵

std::string fName("/path/to/cameraParams.yml");
cv::FileStorage fs(fName, cv::FileStorage::WRITE);
fs << "camera matrix" << cameraMatrix;

一切正常。但是一旦我将文件格式从YAML更改为XML

std::string fName("/path/to/cameraParams.xml");

我收到一个错误

terminate called after throwing an instance of 'cv::Exception'
what():  OpenCV(4.0.0-pre) /home/shura/software.downloads/libraries/opencv/opencv/modules/core/src/persistence_xml.cpp:83: error: (-5:Bad argument) Key name may only contain alphanumeric characters [a-zA-Z0-9], '-' and '_' in function 'writeTag'

正如我所意识到的,原因是XML 格式不允许标签中有空格,而YAML 允许。所以对于YAML,下面的文件是完全有效的

%YAML:1.0
---
camera matrix: !!opencv-matrix

XML 不允许这样的事情

<?xml version="1.0"?>
<opencv_storage>
<camera matrix type_id="opencv-matrix">

只要我用下划线替换“相机矩阵”中的空格,一切正常。

fs << "camera_matrix" << cameraMatrix;

我发现hereXML 格式对标签名称中可以包含的符号有一些限制。特别是,不允许使用名称中的斜杠。标签中似乎允许使用点,但出于某种原因,OpenCV 拒绝使用包含点的标签。

【讨论】:

我想你可以对路径进行编码,例如作为 2 位十六进制值的序列。

以上是关于在 FileStorage 中使用路径作为键的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 机器学习函数需要 CvFileStorage* 而不是 cv::FileStorage*

SpringBoot - FileStorage Starter场景启动器

OpenCV Python API 的 FileStorage

如何将文件路径作为 bash 脚本中的参数传递给函数? [复制]

在 json 中加入多个 json 文件,并将其路径作为键

如何将向量<Dmatch> 写入 FileStorage