Fix DMatch and Keypoint I/O in FileStorage
authorVladislav Sovrasov <sovrasov.vlad@gmail.com>
Wed, 1 Mar 2017 11:30:30 +0000 (14:30 +0300)
committerVladislav Sovrasov <sovrasov.vlad@gmail.com>
Wed, 1 Mar 2017 12:07:38 +0000 (15:07 +0300)
modules/core/include/opencv2/core/persistence.hpp
modules/core/src/persistence.cpp
modules/core/test/test_io.cpp

index 3f18d54..61d1d27 100644 (file)
@@ -945,12 +945,53 @@ void write(FileStorage& fs, const Scalar_<_Tp>& s )
 }
 
 static inline
+void write(FileStorage& fs, const KeyPoint& kpt )
+{
+    write(fs, kpt.pt.x);
+    write(fs, kpt.pt.y);
+    write(fs, kpt.size);
+    write(fs, kpt.angle);
+    write(fs, kpt.response);
+    write(fs, kpt.octave);
+    write(fs, kpt.class_id);
+}
+
+static inline
+void write(FileStorage& fs, const DMatch& m )
+{
+    write(fs, m.queryIdx);
+    write(fs, m.trainIdx);
+    write(fs, m.imgIdx);
+    write(fs, m.distance);
+}
+
+static inline
 void write(FileStorage& fs, const Range& r )
 {
     write(fs, r.start);
     write(fs, r.end);
 }
 
+static inline
+void write( FileStorage& fs, const std::vector<KeyPoint>& vec )
+{
+    size_t npoints = vec.size();
+    for(size_t i = 0; i < npoints; i++ )
+    {
+        write(fs, vec[i]);
+    }
+}
+
+static inline
+void write( FileStorage& fs, const std::vector<DMatch>& vec )
+{
+    size_t npoints = vec.size();
+    for(size_t i = 0; i < npoints; i++ )
+    {
+        write(fs, vec[i]);
+    }
+}
+
 template<typename _Tp> static inline
 void write( FileStorage& fs, const std::vector<_Tp>& vec )
 {
@@ -1096,6 +1137,24 @@ void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>&
     }
 }
 
+static inline
+void read( const FileNode& node, std::vector<KeyPoint>& vec, const std::vector<KeyPoint>& default_value )
+{
+    if(!node.node)
+        vec = default_value;
+    else
+        read(node, vec);
+}
+
+static inline
+void read( const FileNode& node, std::vector<DMatch>& vec, const std::vector<DMatch>& default_value )
+{
+    if(!node.node)
+        vec = default_value;
+    else
+        read(node, vec);
+}
+
 //! @} FileNode
 
 //! @relates cv::FileStorage
index 946875f..cfe44e8 100644 (file)
@@ -7283,14 +7283,7 @@ void write(FileStorage& fs, const String& objname, const std::vector<KeyPoint>&
     int i, npoints = (int)keypoints.size();
     for( i = 0; i < npoints; i++ )
     {
-        const KeyPoint& kpt = keypoints[i];
-        cv::write(fs, kpt.pt.x);
-        cv::write(fs, kpt.pt.y);
-        cv::write(fs, kpt.size);
-        cv::write(fs, kpt.angle);
-        cv::write(fs, kpt.response);
-        cv::write(fs, kpt.octave);
-        cv::write(fs, kpt.class_id);
+        write(fs, keypoints[i]);
     }
 }
 
@@ -7315,11 +7308,7 @@ void write(FileStorage& fs, const String& objname, const std::vector<DMatch>& ma
     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);
+        write(fs, matches[i]);
     }
 }
 
index 880d5cb..910d6d4 100644 (file)
@@ -1013,3 +1013,74 @@ TEST(Core_InputOutput, filestorage_yaml_advanvced_type_heading)
 
     ASSERT_EQ(cv::norm(inputMatrix, actualMatrix, NORM_INF), 0.);
 }
+
+TEST(Core_InputOutput, filestorage_keypoints_io)
+{
+    vector<vector<KeyPoint> > kptsVec;
+    vector<KeyPoint> kpts;
+    kpts.push_back(KeyPoint(0, 0, 1.1f));
+    kpts.push_back(KeyPoint(1, 1, 1.1f));
+    kptsVec.push_back(kpts);
+    kpts.clear();
+    kpts.push_back(KeyPoint(0, 0, 1.1f, 10.1f, 34.5f, 10, 11));
+    kptsVec.push_back(kpts);
+
+    FileStorage writer("", FileStorage::WRITE + FileStorage::MEMORY + FileStorage::FORMAT_XML);
+    writer << "keypoints" << kptsVec;
+    String content = writer.releaseAndGetString();
+
+    FileStorage reader(content, FileStorage::READ + FileStorage::MEMORY);
+    vector<vector<KeyPoint> > readKptsVec;
+    reader["keypoints"] >> readKptsVec;
+
+    ASSERT_EQ(kptsVec.size(), readKptsVec.size());
+
+    for(size_t i = 0; i < kptsVec.size(); i++)
+    {
+        ASSERT_EQ(kptsVec[i].size(), readKptsVec[i].size());
+        for(size_t j = 0; j < kptsVec[i].size(); j++)
+        {
+            ASSERT_FLOAT_EQ(kptsVec[i][j].pt.x, readKptsVec[i][j].pt.x);
+            ASSERT_FLOAT_EQ(kptsVec[i][j].pt.y, readKptsVec[i][j].pt.y);
+            ASSERT_FLOAT_EQ(kptsVec[i][j].angle, readKptsVec[i][j].angle);
+            ASSERT_FLOAT_EQ(kptsVec[i][j].size, readKptsVec[i][j].size);
+            ASSERT_FLOAT_EQ(kptsVec[i][j].response, readKptsVec[i][j].response);
+            ASSERT_EQ(kptsVec[i][j].octave, readKptsVec[i][j].octave);
+            ASSERT_EQ(kptsVec[i][j].class_id, readKptsVec[i][j].class_id);
+        }
+    }
+}
+
+TEST(Core_InputOutput, filestorage_dmatch_io)
+{
+    vector<vector<DMatch> > matchesVec;
+    vector<DMatch> matches;
+    matches.push_back(DMatch(1, 0, 10, 11.5f));
+    matches.push_back(DMatch(2, 1, 11, 21.5f));
+    matchesVec.push_back(matches);
+    matches.clear();
+    matches.push_back(DMatch(22, 10, 1, 1.5f));
+    matchesVec.push_back(matches);
+
+    FileStorage writer("", FileStorage::WRITE + FileStorage::MEMORY + FileStorage::FORMAT_XML);
+    writer << "dmatches" << matchesVec;
+    String content = writer.releaseAndGetString();
+
+    FileStorage reader(content, FileStorage::READ + FileStorage::MEMORY);
+    vector<vector<DMatch> > readKptsVec;
+    reader["dmatches"] >> readKptsVec;
+
+    ASSERT_EQ(matchesVec.size(), readKptsVec.size());
+
+    for(size_t i = 0; i < matchesVec.size(); i++)
+    {
+        ASSERT_EQ(matchesVec[i].size(), readKptsVec[i].size());
+        for(size_t j = 0; j < matchesVec[i].size(); j++)
+        {
+            ASSERT_FLOAT_EQ(matchesVec[i][j].distance, readKptsVec[i][j].distance);
+            ASSERT_EQ(matchesVec[i][j].imgIdx, readKptsVec[i][j].imgIdx);
+            ASSERT_EQ(matchesVec[i][j].queryIdx, readKptsVec[i][j].queryIdx);
+            ASSERT_EQ(matchesVec[i][j].trainIdx, readKptsVec[i][j].trainIdx);
+        }
+    }
+}