在 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::FileStorage
class 的真正限制吗?或者有没有办法绕过它?
最终结果应该是这样的:
"/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