Merge pull request #11935 from mattmyne:filestorage_matx
authorMatt Bennett <m.bennett@freedomsensors.com>
Fri, 9 Nov 2018 17:05:59 +0000 (17:05 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Fri, 9 Nov 2018 17:05:59 +0000 (20:05 +0300)
* Support for Matx read/write by FileStorage

* Only empty filestorage read now produces default Matx. Split Matx IO test into smaller units. Test checks for exception thrown if reading a Mat into a Matx of different size.

modules/core/include/opencv2/core/persistence.hpp
modules/core/test/test_io.cpp

index 2832046..a0f7e1e 100644 (file)
@@ -751,6 +751,17 @@ template<typename _Tp, int cn> static inline void read(const FileNode& node, Vec
     value = temp.size() != cn ? default_value : Vec<_Tp, cn>(&temp[0]);
 }
 
+template<typename _Tp, int m, int n> static inline void read(const FileNode& node, Matx<_Tp, m, n>& value, const Matx<_Tp, m, n>& default_matx = Matx<_Tp, m, n>())
+{
+    Mat temp;
+    read(node, temp); // read as a Mat class
+
+    if (temp.empty())
+        value = default_matx;
+    else
+        value = Matx<_Tp, m, n>(temp);
+}
+
 template<typename _Tp> static inline void read(const FileNode& node, Scalar_<_Tp>& value, const Scalar_<_Tp>& default_value)
 {
     std::vector<_Tp> temp; FileNodeIterator it = node.begin(); it >> temp;
@@ -931,6 +942,12 @@ void write(FileStorage& fs, const Vec<_Tp, cn>& v )
         write(fs, v.val[i]);
 }
 
+template<typename _Tp, int m, int n> static inline
+void write(FileStorage& fs, const Matx<_Tp, m, n>& x )
+{
+    write(fs, Mat(x)); // write as a Mat class
+}
+
 template<typename _Tp> static inline
 void write(FileStorage& fs, const Scalar_<_Tp>& s )
 {
@@ -996,6 +1013,12 @@ void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v )
     write(fs, v);
 }
 
+template<typename _Tp, int m, int n> static inline
+void write(FileStorage& fs, const String& name, const Matx<_Tp, m, n>& x )
+{
+    write(fs, name, Mat(x)); // write as a Mat class
+}
+
 template<typename _Tp> static inline
 void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s )
 {
index 282ccce..8554935 100644 (file)
@@ -1006,6 +1006,60 @@ TEST(Core_InputOutput, filestorage_yaml_advanvced_type_heading)
     ASSERT_EQ(cv::norm(inputMatrix, actualMatrix, NORM_INF), 0.);
 }
 
+TEST(Core_InputOutput, filestorage_matx_io)
+{
+    Matx33d matxTest(1.234, 2, 3, 4, 5, 6, 7, 8, 9.876);
+
+    FileStorage writer("", FileStorage::WRITE | FileStorage::MEMORY);
+    writer << "matxTest" << matxTest;
+    String content = writer.releaseAndGetString();
+
+    FileStorage reader(content, FileStorage::READ | FileStorage::MEMORY);
+    Matx33d matxTestRead;
+    reader["matxTest"] >> matxTestRead;
+    ASSERT_TRUE( cv::norm(matxTest, matxTestRead, NORM_INF) == 0 );
+
+    reader.release();
+}
+
+TEST(Core_InputOutput, filestorage_matx_io_size_mismatch)
+{
+    Matx32d matxTestWrongSize(1, 2, 3, 4, 5, 6);
+
+    FileStorage writer("", FileStorage::WRITE | FileStorage::MEMORY);
+    writer << "matxTestWrongSize" << matxTestWrongSize;
+    String content = writer.releaseAndGetString();
+
+    FileStorage reader(content, FileStorage::READ | FileStorage::MEMORY);
+    Matx33d matxTestRead;
+    try
+    {
+        reader["matxTestWrongSize"] >> matxTestRead;
+        FAIL() << "wrong size matrix read but no exception thrown";
+    }
+    catch (const std::exception&)
+    {
+    }
+
+    reader.release();
+}
+
+TEST(Core_InputOutput, filestorage_matx_io_with_mat)
+{
+    Mat normalMat = Mat::eye(3, 3, CV_64F);
+
+    FileStorage writer("", FileStorage::WRITE | FileStorage::MEMORY);
+    writer << "normalMat" << normalMat;
+    String content = writer.releaseAndGetString();
+
+    FileStorage reader(content, FileStorage::READ | FileStorage::MEMORY);
+    Matx33d matxTestRead;
+    reader["normalMat"] >> matxTestRead;
+    ASSERT_TRUE( cv::norm(Mat::eye(3, 3, CV_64F), matxTestRead, NORM_INF) == 0 );
+
+    reader.release();
+}
+
 TEST(Core_InputOutput, filestorage_keypoints_vec_vec_io)
 {
     vector<vector<KeyPoint> > kptsVec;