diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp index eec304d6b7..17686dd0d9 100644 --- a/modules/core/include/opencv2/core/persistence.hpp +++ b/modules/core/include/opencv2/core/persistence.hpp @@ -660,6 +660,7 @@ CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value CV_EXPORTS void write( FileStorage& fs, const String& name, const Mat& value ); CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value ); CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); +CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector& value); CV_EXPORTS void writeScalar( FileStorage& fs, int value ); CV_EXPORTS void writeScalar( FileStorage& fs, float value ); @@ -678,6 +679,7 @@ CV_EXPORTS void read(const FileNode& node, String& value, const String& default_ CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() ); CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() ); CV_EXPORTS void read(const FileNode& node, std::vector& keypoints); +CV_EXPORTS void read(const FileNode& node, std::vector& matches); template static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value) { diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 002ff01d09..9c7b0f236b 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -5594,6 +5594,35 @@ void read(const FileNode& node, std::vector& keypoints) } } + +void write(FileStorage& fs, const String& objname, const std::vector& matches) +{ + cv::internal::WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW); + + int i, n = (int)matches.size(); + for( i = 0; i < n; i++ ) + { + const DMatch& m = matches[i]; + cv::write(fs, m.queryIdx); + cv::write(fs, m.trainIdx); + cv::write(fs, m.imgIdx); + cv::write(fs, m.distance); + } +} + +void read(const FileNode& node, std::vector& matches) +{ + matches.resize(0); + FileNodeIterator it = node.begin(), it_end = node.end(); + for( ; it != it_end; ) + { + DMatch m; + it >> m.queryIdx >> m.trainIdx >> m.imgIdx >> m.distance; + matches.push_back(m); + } +} + + int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); } bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; } diff --git a/modules/features2d/test/test_matchers_algorithmic.cpp b/modules/features2d/test/test_matchers_algorithmic.cpp index ec71e5a5ad..8f66648599 100644 --- a/modules/features2d/test/test_matchers_algorithmic.cpp +++ b/modules/features2d/test/test_matchers_algorithmic.cpp @@ -543,3 +543,13 @@ TEST( Features2d_DescriptorMatcher_FlannBased, regression ) DescriptorMatcher::create("FlannBased"), 0.04f ); test.safe_run(); } + +TEST( Features2d_DMatch, read_write ) +{ + FileStorage fs(".xml", FileStorage::WRITE + FileStorage::MEMORY); + vector matches; + matches.push_back(DMatch(1,2,3,4.5f)); + fs << "Match" << matches; + String str = fs.releaseAndGetString(); + ASSERT_NE( strstr(str.c_str(), "4.5"), (char*)0 ); +}