尝试使用 yaml-cpp 解析 OpenCV YAML 输出

发布于 2024-08-29 09:04:41 字数 1060 浏览 6 评论 0原文

我有一系列 OpenCv 生成的 YAML 文件,并想用 yaml-cpp 解析它们

,我在简单的事情上做得很好,但矩阵表示很困难。

# Center of table
tableCenter: !!opencv-matrix
   rows: 1
   cols: 2
   dt: f
   data: [ 240,    240]

这应该映射到

240
240

类型为 float 的向量。我的代码看起来像:

#include "yaml.h"
#include <fstream>
#include <string>

struct Matrix {
    int x;
};

void operator >> (const YAML::Node& node, Matrix& matrix) {
   unsigned rows;
   node["rows"] >> rows;
}

int main()
{
   std::ifstream fin("monsters.yaml");
   YAML::Parser parser(fin);
   YAML::Node doc;

    Matrix m;
    doc["tableCenter"] >> m;

   return 0;
}

但是我

terminate called after throwing an instance of 'YAML::BadDereference'
  what():  yaml-cpp: error at line 0, column 0: bad dereference
Abort trap

搜索了一些有关 yaml-cpp 的文档,但除了有关解析和发出的简短介绍性示例之外,似乎没有任何文档。不幸的是,这两者在这种特殊情况下都无济于事。

据我了解, !! 表明这是一个用户定义的类型,但我没有看到 yaml-cpp 如何解析它。

I've got a series of OpenCv generated YAML files and would like to parse them with yaml-cpp

I'm doing okay on simple stuff, but the matrix representation is proving difficult.

# Center of table
tableCenter: !!opencv-matrix
   rows: 1
   cols: 2
   dt: f
   data: [ 240,    240]

This should map into the vector

240
240

with type float. My code looks like:

#include "yaml.h"
#include <fstream>
#include <string>

struct Matrix {
    int x;
};

void operator >> (const YAML::Node& node, Matrix& matrix) {
   unsigned rows;
   node["rows"] >> rows;
}

int main()
{
   std::ifstream fin("monsters.yaml");
   YAML::Parser parser(fin);
   YAML::Node doc;

    Matrix m;
    doc["tableCenter"] >> m;

   return 0;
}

But I get

terminate called after throwing an instance of 'YAML::BadDereference'
  what():  yaml-cpp: error at line 0, column 0: bad dereference
Abort trap

I searched around for some documentation for yaml-cpp, but there doesn't seem to be any, aside from a short introductory example on parsing and emitting. Unfortunately, neither of these two help in this particular circumstance.

As I understand, the !! indicate that this is a user-defined type, but I don't see with yaml-cpp how to parse that.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

那伤。 2024-09-05 09:04:41

您必须告诉 yaml-cpp 如何解析此类型。由于 C++ 不是动态类型的,因此它无法检测您想要的数据类型并从头开始创建它 - 您必须直接告诉它。标记节点实际上只是为了您自己,而不是为了解析器(它只会忠实地为您存储它)。

我不太确定 OpenCV 矩阵是如何存储的,但如果是这样的:

class Matrix {
public:
   Matrix(unsigned r, unsigned c, const std::vector<float>& d): rows(r), cols(c), data(d) { /* init */ }
   Matrix(const Matrix&) { /* copy */ }
   ~Matrix() { /* delete */ }
   Matrix& operator = (const Matrix&) { /* assign */ }

private:
   unsigned rows, cols;
   std::vector<float> data;
};

那么你可以写类似

void operator >> (const YAML::Node& node, Matrix& matrix) {
   unsigned rows, cols;
   std::vector<float> data;
   node["rows"] >> rows;
   node["cols"] >> cols;
   node["data"] >> data;
   matrix = Matrix(rows, cols, data);
}

Edit 的东西,看起来你到这里为止都没有问题;但是您缺少解析器将信息加载到 YAML::Node 中的步骤。相反,如下所示:

std::ifstream fin("monsters.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc); // <-- this line was missing!

Matrix m;
doc["tableCenter"] >> m;

注意:我猜测 dt: f 意味着“数据类型是浮点型”。如果是这样的话,这实际上取决于 Matrix 类如何处理这个问题。如果每种数据类型都有不同的类(或模板类),则必须首先读取该字段,然后选择要实例化的类型。 (如果您知道它始终是浮动的,当然,这会让您的生活更轻松。)

You have to tell yaml-cpp how to parse this type. Since C++ isn't dynamically typed, it can't detect what data type you want and create it from scratch - you have to tell it directly. Tagging a node is really only for yourself, not for the parser (it'll just faithfully store it for you).

I'm not really sure how an OpenCV matrix is stored, but if it's something like this:

class Matrix {
public:
   Matrix(unsigned r, unsigned c, const std::vector<float>& d): rows(r), cols(c), data(d) { /* init */ }
   Matrix(const Matrix&) { /* copy */ }
   ~Matrix() { /* delete */ }
   Matrix& operator = (const Matrix&) { /* assign */ }

private:
   unsigned rows, cols;
   std::vector<float> data;
};

then you can write something like

void operator >> (const YAML::Node& node, Matrix& matrix) {
   unsigned rows, cols;
   std::vector<float> data;
   node["rows"] >> rows;
   node["cols"] >> cols;
   node["data"] >> data;
   matrix = Matrix(rows, cols, data);
}

Edit It appears that you're ok up until here; but you're missing the step where the parser loads the information into the YAML::Node. Instead, se it like:

std::ifstream fin("monsters.yaml");
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc); // <-- this line was missing!

Matrix m;
doc["tableCenter"] >> m;

Note: I'm guessing dt: f means "data type is float". If that's the case, it'll really depend on how the Matrix class handles this. If you have a different class for each data type (or a templated class), you'll have to read that field first, and then choose which type to instantiate. (If you know it'll always be float, that'll make your life easier, of course.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文