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

Viewed 248

According to the OpenCV Docs, we can use cv::FileStorage to read/write custom data structure from/to config files (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;
}

The code above can compile. But if the line class MyData { }; is replaced with using MyData = Eigen::Vector2d;, an error occurs:

/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());
      |     ~~~~^~~~~~~~~~~~~~~~~~

This confuses me a lot. Why Eigen::Matrix doesn't work while a normal custom structure works? Thanks ahead for any help.

1 Answers

The issue is due to the intruduction of namespace, indeed you can get a similar issue with this code:

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

To fix the your compilation error, you need to add the read function inside the same namespace (or 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;
}

The Argument Dependent Lookup (ADL) is looking inside the cv namespace and the namespace where the type is declared in your case the function is in neither of those.

Related