3

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.

VictorBian
  • 675
  • 1
  • 4
  • 17
  • why are you confused? the compiler is looking for the equivalent of static void read(const cv::FileNode& node, MyData& value, const MyData& default_value = MyData()) { } for Eigen::Vector2d; Eigen::Vector2d is probably a typedef of Eigen::Matrix – Alessandro Teruzzi Jun 15 '21 at 11:58
  • @Alessandro Teruzzi. Of course `Eigen::Vector2d` is a typedef of `Eigen::Matrix`. But with `using MyData = Eigen::Vector2d;`, the function `void read()` is still there, right? Why can't the compiler find it? – VictorBian Jun 15 '21 at 12:24
  • I see, interestingly, the compiler is complaining about not finding a match for (const ref FileNode, ref matrix, value matrix) and you have provided (const ref FileNode, ref matrix, const ref matrix). Anything else in the error message? – Alessandro Teruzzi Jun 15 '21 at 13:05
  • @Alessandro Teruzzi. There seems to be no more useful information in the error message. Anyway, [here](https://pastebin.com/cjdWjdfC) is the complete error info. – VictorBian Jun 15 '21 at 14:34

1 Answers1

3

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.

Alessandro Teruzzi
  • 3,918
  • 1
  • 27
  • 41