Read/write Eigen::Matrix 和 cv::Filestorage

Read/write Eigen::Matrix with cv::Filestorage

根据OpenCV Docs,我们可以使用cv::FileStorage到read/write自定义数据结构from/to配置文件(XML、YAML、JSON):

#include <opencv2/opencv.hpp>
#include <Eigen/Core>

class MyData { };

static void read(const cv::FileNode& node, MyData& value,
    const MyData& default_value = MyData()) { }

int main()
{
    cv::FileStorage fs;
    MyData md;
    fs["MyData"] >> md;
}

以上代码可以编译。但是如果把class MyData { };这一行换成using MyData = Eigen::Vector2d;,就会出现错误:

/usr/include/opencv4/opencv2/core/persistence.hpp:1281: error: no matching function for call to 'read(const cv::FileNode&, Eigen::Matrix<double, 2, 1>&, Eigen::Matrix<double, 2, 1>)'
In file included from /usr/include/opencv4/opencv2/core.hpp:59,
                 from /usr/include/opencv4/opencv2/opencv.hpp:52,
                 from ../main.cpp:1:
/usr/include/opencv4/opencv2/core/persistence.hpp: In instantiation of 'void cv::operator>>(const cv::FileNode&, _Tp&) [with _Tp = Eigen::Matrix<double, 2, 1>]':
../main.cpp:21:21:   required from here
/usr/include/opencv4/opencv2/core/persistence.hpp:1281:9: error: no matching function for call to 'read(const cv::FileNode&, Eigen::Matrix<double, 2, 1>&, Eigen::Matrix<double, 2, 1>)'
 1281 |     read( n, value, _Tp());
      |     ~~~~^~~~~~~~~~~~~~~~~~

这让我很困惑。为什么 Eigen::Matrix 不起作用,而正常的自定义结构有效?在此先感谢您的帮助。

这个问题是由于命名空间的引入,实际上你可以用这段代码得到类似的问题:

#include <opencv2/opencv.hpp>

namespace X 
{
  struct MyData {};
}

static void read(const cv::FileNode& node, X::MyData& value,
  const X::MyData& default_value = X::MyData()) { }

int main()
{
  cv::FileStorage fs;
  X::MyData md;
  fs["MyData"] >> md;
}

要修复您的编译错误,您需要在同一命名空间(或 cv one)中添加读取函数:

#include <opencv2/opencv.hpp>
#include <Eigen/Core>

using MyData = Eigen::Vector2d;

namespace Eigen //or cv
{
  static void read(const cv::FileNode& node, MyData& value,
    const MyData& default_value = MyData()) { }
}

int main()
{
   cv::FileStorage fs;
   MyData md;
   fs["MyData"] >> md;
}

参数相关查找 (ADL) 正在查找 cv 命名空间和声明类型的命名空间,在您的情况下,函数不在这两个命名空间中。