Commit 0451629e authored by Alexander Alekhin's avatar Alexander Alekhin

core(persistence): resolve DMatch/KeyPoint problem

parent 86b55b39
...@@ -44,6 +44,11 @@ ...@@ -44,6 +44,11 @@
#ifndef OPENCV_CORE_PERSISTENCE_HPP #ifndef OPENCV_CORE_PERSISTENCE_HPP
#define OPENCV_CORE_PERSISTENCE_HPP #define OPENCV_CORE_PERSISTENCE_HPP
#ifndef CV_DOXYGEN
/// Define to support persistence legacy formats
#define CV__LEGACY_PERSISTENCE
#endif
#ifndef __cplusplus #ifndef __cplusplus
# error persistence.hpp header must be compiled as C++ # error persistence.hpp header must be compiled as C++
#endif #endif
...@@ -700,8 +705,10 @@ CV_EXPORTS void write( FileStorage& fs, const String& name, double value ); ...@@ -700,8 +705,10 @@ CV_EXPORTS void write( FileStorage& fs, const String& name, double value );
CV_EXPORTS void write( FileStorage& fs, const String& name, const String& value ); 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 Mat& value );
CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value ); CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value );
#ifdef CV__LEGACY_PERSISTENCE
CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& value); CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& value);
CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<DMatch>& value); CV_EXPORTS void write( FileStorage& fs, const String& name, const std::vector<DMatch>& value);
#endif
CV_EXPORTS void writeScalar( FileStorage& fs, int value ); CV_EXPORTS void writeScalar( FileStorage& fs, int value );
CV_EXPORTS void writeScalar( FileStorage& fs, float value ); CV_EXPORTS void writeScalar( FileStorage& fs, float value );
...@@ -720,8 +727,12 @@ CV_EXPORTS void read(const FileNode& node, String& value, const String& default_ ...@@ -720,8 +727,12 @@ CV_EXPORTS void read(const FileNode& node, String& value, const String& default_
CV_EXPORTS void read(const FileNode& node, std::string& value, const std::string& default_value); CV_EXPORTS void read(const FileNode& node, std::string& value, const std::string& default_value);
CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() ); 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, SparseMat& mat, const SparseMat& default_mat = SparseMat() );
#ifdef CV__LEGACY_PERSISTENCE
CV_EXPORTS void read(const FileNode& node, std::vector<KeyPoint>& keypoints); CV_EXPORTS void read(const FileNode& node, std::vector<KeyPoint>& keypoints);
CV_EXPORTS void read(const FileNode& node, std::vector<DMatch>& matches); CV_EXPORTS void read(const FileNode& node, std::vector<DMatch>& matches);
#endif
CV_EXPORTS void read(const FileNode& node, KeyPoint& value, const KeyPoint& default_value);
CV_EXPORTS void read(const FileNode& node, DMatch& value, const DMatch& default_value);
template<typename _Tp> static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value) template<typename _Tp> static inline void read(const FileNode& node, Point_<_Tp>& value, const Point_<_Tp>& default_value)
{ {
...@@ -948,27 +959,6 @@ void write(FileStorage& fs, const Scalar_<_Tp>& s ) ...@@ -948,27 +959,6 @@ void write(FileStorage& fs, const Scalar_<_Tp>& s )
write(fs, s.val[3]); write(fs, s.val[3]);
} }
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 static inline
void write(FileStorage& fs, const Range& r ) void write(FileStorage& fs, const Range& r )
{ {
...@@ -976,26 +966,6 @@ void write(FileStorage& fs, const Range& r ) ...@@ -976,26 +966,6 @@ void write(FileStorage& fs, const Range& r )
write(fs, r.end); 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 template<typename _Tp> static inline
void write( FileStorage& fs, const std::vector<_Tp>& vec ) void write( FileStorage& fs, const std::vector<_Tp>& vec )
{ {
...@@ -1060,17 +1030,26 @@ void write(FileStorage& fs, const String& name, const Range& r ) ...@@ -1060,17 +1030,26 @@ void write(FileStorage& fs, const String& name, const Range& r )
} }
static inline static inline
void write(FileStorage& fs, const String& name, const KeyPoint& r ) void write(FileStorage& fs, const String& name, const KeyPoint& kpt)
{ {
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, r); 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 static inline
void write(FileStorage& fs, const String& name, const DMatch& r ) void write(FileStorage& fs, const String& name, const DMatch& m)
{ {
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW); cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, r); write(fs, m.queryIdx);
write(fs, m.trainIdx);
write(fs, m.imgIdx);
write(fs, m.distance);
} }
template<typename _Tp> static inline template<typename _Tp> static inline
...@@ -1091,6 +1070,24 @@ void write( FileStorage& fs, const String& name, const std::vector< std::vector< ...@@ -1091,6 +1070,24 @@ void write( FileStorage& fs, const String& name, const std::vector< std::vector<
} }
} }
#ifdef CV__LEGACY_PERSISTENCE
// This code is not needed anymore, but it is preserved here to keep source compatibility
// Implementation is similar to templates instantiations
static inline void write(FileStorage& fs, const KeyPoint& kpt) { write(fs, String(), kpt); }
static inline void write(FileStorage& fs, const DMatch& m) { write(fs, String(), m); }
static inline void write(FileStorage& fs, const std::vector<KeyPoint>& vec)
{
cv::internal::VecWriterProxy<KeyPoint, 0> w(&fs);
w(vec);
}
static inline void write(FileStorage& fs, const std::vector<DMatch>& vec)
{
cv::internal::VecWriterProxy<DMatch, 0> w(&fs);
w(vec);
}
#endif
//! @} FileStorage //! @} FileStorage
//! @relates cv::FileNode //! @relates cv::FileNode
...@@ -1258,12 +1255,6 @@ void operator >> (const FileNode& n, std::vector<_Tp>& vec) ...@@ -1258,12 +1255,6 @@ void operator >> (const FileNode& n, std::vector<_Tp>& vec)
/** @brief Reads KeyPoint from a file storage. /** @brief Reads KeyPoint from a file storage.
*/ */
//It needs special handling because it contains two types of fields, int & float. //It needs special handling because it contains two types of fields, int & float.
static inline
void operator >> (const FileNode& n, std::vector<KeyPoint>& vec)
{
read(n, vec);
}
static inline static inline
void operator >> (const FileNode& n, KeyPoint& kpt) void operator >> (const FileNode& n, KeyPoint& kpt)
{ {
...@@ -1271,15 +1262,22 @@ void operator >> (const FileNode& n, KeyPoint& kpt) ...@@ -1271,15 +1262,22 @@ void operator >> (const FileNode& n, KeyPoint& kpt)
it >> kpt.pt.x >> kpt.pt.y >> kpt.size >> kpt.angle >> kpt.response >> kpt.octave >> kpt.class_id; it >> kpt.pt.x >> kpt.pt.y >> kpt.size >> kpt.angle >> kpt.response >> kpt.octave >> kpt.class_id;
} }
/** @brief Reads DMatch from a file storage. #ifdef CV__LEGACY_PERSISTENCE
*/ static inline
//It needs special handling because it contains two types of fields, int & float. void operator >> (const FileNode& n, std::vector<KeyPoint>& vec)
{
read(n, vec);
}
static inline static inline
void operator >> (const FileNode& n, std::vector<DMatch>& vec) void operator >> (const FileNode& n, std::vector<DMatch>& vec)
{ {
read(n, vec); read(n, vec);
} }
#endif
/** @brief Reads DMatch from a file storage.
*/
//It needs special handling because it contains two types of fields, int & float.
static inline static inline
void operator >> (const FileNode& n, DMatch& m) void operator >> (const FileNode& n, DMatch& m)
{ {
......
...@@ -7333,21 +7333,45 @@ void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat ) ...@@ -7333,21 +7333,45 @@ void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat )
m->copyToSparseMat(mat); m->copyToSparseMat(mat);
} }
void write(FileStorage& fs, const String& objname, const std::vector<KeyPoint>& keypoints) CV_EXPORTS void read(const FileNode& node, KeyPoint& value, const KeyPoint& default_value)
{ {
cv::internal::WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW); if( node.empty() )
{
value = default_value;
return;
}
node >> value;
}
int i, npoints = (int)keypoints.size(); CV_EXPORTS void read(const FileNode& node, DMatch& value, const DMatch& default_value)
for( i = 0; i < npoints; i++ ) {
if( node.empty() )
{ {
write(fs, keypoints[i]); value = default_value;
return;
} }
node >> value;
} }
#ifdef CV__LEGACY_PERSISTENCE
void write( FileStorage& fs, const String& name, const std::vector<KeyPoint>& vec)
{
// from template implementation
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ);
write(fs, vec);
}
void read(const FileNode& node, std::vector<KeyPoint>& keypoints) void read(const FileNode& node, std::vector<KeyPoint>& keypoints)
{ {
keypoints.resize(0); FileNode first_node = *(node.begin());
if (first_node.isSeq())
{
// modern scheme
FileNodeIterator it = node.begin();
it >> keypoints;
return;
}
keypoints.clear();
FileNodeIterator it = node.begin(), it_end = node.end(); FileNodeIterator it = node.begin(), it_end = node.end();
for( ; it != it_end; ) for( ; it != it_end; )
{ {
...@@ -7357,21 +7381,24 @@ void read(const FileNode& node, std::vector<KeyPoint>& keypoints) ...@@ -7357,21 +7381,24 @@ void read(const FileNode& node, std::vector<KeyPoint>& keypoints)
} }
} }
void write( FileStorage& fs, const String& name, const std::vector<DMatch>& vec)
void write(FileStorage& fs, const String& objname, const std::vector<DMatch>& matches)
{ {
cv::internal::WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW); // from template implementation
cv::internal::WriteStructContext ws(fs, name, FileNode::SEQ);
int i, n = (int)matches.size(); write(fs, vec);
for( i = 0; i < n; i++ )
{
write(fs, matches[i]);
}
} }
void read(const FileNode& node, std::vector<DMatch>& matches) void read(const FileNode& node, std::vector<DMatch>& matches)
{ {
matches.resize(0); FileNode first_node = *(node.begin());
if (first_node.isSeq())
{
// modern scheme
FileNodeIterator it = node.begin();
it >> matches;
return;
}
matches.clear();
FileNodeIterator it = node.begin(), it_end = node.end(); FileNodeIterator it = node.begin(), it_end = node.end();
for( ; it != it_end; ) for( ; it != it_end; )
{ {
...@@ -7380,7 +7407,7 @@ void read(const FileNode& node, std::vector<DMatch>& matches) ...@@ -7380,7 +7407,7 @@ void read(const FileNode& node, std::vector<DMatch>& matches)
matches.push_back(m); matches.push_back(m);
} }
} }
#endif
int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); } int FileNode::type() const { return !node ? NONE : (node->tag & TYPE_MASK); }
bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; } bool FileNode::isNamed() const { return !node ? false : (node->tag & NAMED) != 0; }
......
...@@ -1146,15 +1146,19 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector) ...@@ -1146,15 +1146,19 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector)
EXPECT_STREQ(fs_result.c_str(), EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n" "%YAML:1.0\n"
"---\n" "---\n"
"dv: [ 1, 2, 3, -1.5000000000000000e+000, 2, 3, 4,\n" "dv:\n"
" 1.5000000000000000e+000, 3, 2, 1, 5.0000000000000000e-001 ]\n" " - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
" - [ 2, 3, 4, 1.5000000000000000e+000 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
); );
#else #else
EXPECT_STREQ(fs_result.c_str(), EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n" "%YAML:1.0\n"
"---\n" "---\n"
"dv: [ 1, 2, 3, -1.5000000000000000e+00, 2, 3, 4, 1.5000000000000000e+00,\n" "dv:\n"
" 3, 2, 1, 5.0000000000000000e-01 ]\n" " - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
" - [ 2, 3, 4, 1.5000000000000000e+00 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
); );
#endif #endif
...@@ -1200,19 +1204,26 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector) ...@@ -1200,19 +1204,26 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector)
"%YAML:1.0\n" "%YAML:1.0\n"
"---\n" "---\n"
"dvv:\n" "dvv:\n"
" - [ 1, 2, 3, -1.5000000000000000e+000, 2, 3, 4,\n" " -\n"
" 1.5000000000000000e+000, 3, 2, 1, 5.0000000000000000e-001 ]\n" " - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-001, 1, 2, 3,\n" " - [ 2, 3, 4, 1.5000000000000000e+000 ]\n"
" -1.5000000000000000e+000 ]\n" " - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
" -\n"
" - [ 3, 2, 1, 5.0000000000000000e-001 ]\n"
" - [ 1, 2, 3, -1.5000000000000000e+000 ]\n"
); );
#else #else
EXPECT_STREQ(fs_result.c_str(), EXPECT_STREQ(fs_result.c_str(),
"%YAML:1.0\n" "%YAML:1.0\n"
"---\n" "---\n"
"dvv:\n" "dvv:\n"
" - [ 1, 2, 3, -1.5000000000000000e+00, 2, 3, 4, 1.5000000000000000e+00,\n" " -\n"
" 3, 2, 1, 5.0000000000000000e-01 ]\n" " - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-01, 1, 2, 3, -1.5000000000000000e+00 ]\n" " - [ 2, 3, 4, 1.5000000000000000e+00 ]\n"
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
" -\n"
" - [ 3, 2, 1, 5.0000000000000000e-01 ]\n"
" - [ 1, 2, 3, -1.5000000000000000e+00 ]\n"
); );
#endif #endif
...@@ -1237,6 +1248,219 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector) ...@@ -1237,6 +1248,219 @@ TEST(Core_InputOutput, FileStorage_DMatch_vector_vector)
} }
} }
TEST(Core_InputOutput, FileStorage_KeyPoint)
{
cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
cv::KeyPoint k(Point2f(1, 2), 16, 0, 100, 1, -1);
EXPECT_NO_THROW(fs << "k" << k);
cv::String fs_result = fs.releaseAndGetString();
EXPECT_STREQ(fs_result.c_str(),
"<?xml version=\"1.0\"?>\n"
"<opencv_storage>\n"
"<k>\n"
" 1. 2. 16. 0. 100. 1 -1</k>\n"
"</opencv_storage>\n"
);
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
cv::KeyPoint k_read;
ASSERT_NO_THROW(fs_read["k"] >> k_read);
EXPECT_EQ(k.pt, k_read.pt);
EXPECT_EQ(k.size, k_read.size);
EXPECT_EQ(k.angle, k_read.angle);
EXPECT_EQ(k.response, k_read.response);
EXPECT_EQ(k.octave, k_read.octave);
EXPECT_EQ(k.class_id, k_read.class_id);
}
TEST(Core_InputOutput, FileStorage_KeyPoint_vector)
{
cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1);
cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1);
cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1);
std::vector<cv::KeyPoint> kv;
kv.push_back(k1);
kv.push_back(k2);
kv.push_back(k3);
EXPECT_NO_THROW(fs << "kv" << kv);
cv::String fs_result = fs.releaseAndGetString();
EXPECT_STREQ(fs_result.c_str(),
"<?xml version=\"1.0\"?>\n"
"<opencv_storage>\n"
"<kv>\n"
" <_>\n"
" 1. 2. 16. 0. 100. 1 -1</_>\n"
" <_>\n"
" 2. 3. 16. 45. 100. 1 -1</_>\n"
" <_>\n"
" 1. 2. 16. 90. 100. 1 -1</_></kv>\n"
"</opencv_storage>\n"
);
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
std::vector<cv::KeyPoint> kv_read;
ASSERT_NO_THROW(fs_read["kv"] >> kv_read);
ASSERT_EQ(kv.size(), kv_read.size());
for (size_t i = 0; i < kv.size(); i++)
{
EXPECT_EQ(kv[i].pt, kv_read[i].pt);
EXPECT_EQ(kv[i].size, kv_read[i].size);
EXPECT_EQ(kv[i].angle, kv_read[i].angle);
EXPECT_EQ(kv[i].response, kv_read[i].response);
EXPECT_EQ(kv[i].octave, kv_read[i].octave);
EXPECT_EQ(kv[i].class_id, kv_read[i].class_id);
}
}
TEST(Core_InputOutput, FileStorage_KeyPoint_vector_vector)
{
cv::FileStorage fs("keypoint.xml", cv::FileStorage::WRITE | cv::FileStorage::MEMORY);
cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1);
cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1);
cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1);
std::vector<cv::KeyPoint> kv1;
kv1.push_back(k1);
kv1.push_back(k2);
kv1.push_back(k3);
std::vector<cv::KeyPoint> kv2;
kv2.push_back(k3);
kv2.push_back(k1);
std::vector< std::vector<cv::KeyPoint> > kvv;
kvv.push_back(kv1);
kvv.push_back(kv2);
EXPECT_NO_THROW(fs << "kvv" << kvv);
cv::String fs_result = fs.releaseAndGetString();
EXPECT_STREQ(fs_result.c_str(),
"<?xml version=\"1.0\"?>\n"
"<opencv_storage>\n"
"<kvv>\n"
" <_>\n"
" <_>\n"
" 1. 2. 16. 0. 100. 1 -1</_>\n"
" <_>\n"
" 2. 3. 16. 45. 100. 1 -1</_>\n"
" <_>\n"
" 1. 2. 16. 90. 100. 1 -1</_></_>\n"
" <_>\n"
" <_>\n"
" 1. 2. 16. 90. 100. 1 -1</_>\n"
" <_>\n"
" 1. 2. 16. 0. 100. 1 -1</_></_></kvv>\n"
"</opencv_storage>\n"
);
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
std::vector< std::vector<cv::KeyPoint> > kvv_read;
ASSERT_NO_THROW(fs_read["kvv"] >> kvv_read);
ASSERT_EQ(kvv.size(), kvv_read.size());
for (size_t j = 0; j < kvv.size(); j++)
{
const std::vector<cv::KeyPoint>& kv = kvv[j];
const std::vector<cv::KeyPoint>& kv_read = kvv_read[j];
ASSERT_EQ(kvv.size(), kvv_read.size());
for (size_t i = 0; i < kv.size(); i++)
{
EXPECT_EQ(kv[i].pt, kv_read[i].pt);
EXPECT_EQ(kv[i].size, kv_read[i].size);
EXPECT_EQ(kv[i].angle, kv_read[i].angle);
EXPECT_EQ(kv[i].response, kv_read[i].response);
EXPECT_EQ(kv[i].octave, kv_read[i].octave);
EXPECT_EQ(kv[i].class_id, kv_read[i].class_id);
}
}
}
#ifdef CV__LEGACY_PERSISTENCE
TEST(Core_InputOutput, FileStorage_LEGACY_DMatch_vector)
{
cv::DMatch d1(1, 2, 3, -1.5f);
cv::DMatch d2(2, 3, 4, 1.5f);
cv::DMatch d3(3, 2, 1, 0.5f);
std::vector<cv::DMatch> dv;
dv.push_back(d1);
dv.push_back(d2);
dv.push_back(d3);
String fs_result =
"<?xml version=\"1.0\"?>\n"
"<opencv_storage>\n"
"<dv>\n"
" 1 2 3 -1.5000000000000000e+00 2 3 4 1.5000000000000000e+00 3 2 1\n"
" 5.0000000000000000e-01</dv>\n"
"</opencv_storage>\n"
;
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
std::vector<cv::DMatch> dv_read;
ASSERT_NO_THROW(fs_read["dv"] >> dv_read);
ASSERT_EQ(dv.size(), dv_read.size());
for (size_t i = 0; i < dv.size(); i++)
{
EXPECT_EQ(dv[i].queryIdx, dv_read[i].queryIdx);
EXPECT_EQ(dv[i].trainIdx, dv_read[i].trainIdx);
EXPECT_EQ(dv[i].imgIdx, dv_read[i].imgIdx);
EXPECT_EQ(dv[i].distance, dv_read[i].distance);
}
}
TEST(Core_InputOutput, FileStorage_LEGACY_KeyPoint_vector)
{
cv::KeyPoint k1(Point2f(1, 2), 16, 0, 100, 1, -1);
cv::KeyPoint k2(Point2f(2, 3), 16, 45, 100, 1, -1);
cv::KeyPoint k3(Point2f(1, 2), 16, 90, 100, 1, -1);
std::vector<cv::KeyPoint> kv;
kv.push_back(k1);
kv.push_back(k2);
kv.push_back(k3);
cv::String fs_result =
"<?xml version=\"1.0\"?>\n"
"<opencv_storage>\n"
"<kv>\n"
" 1. 2. 16. 0. 100. 1 -1\n"
" 2. 3. 16. 45. 100. 1 -1\n"
" 1. 2. 16. 90. 100. 1 -1</kv>\n"
"</opencv_storage>\n"
;
cv::FileStorage fs_read(fs_result, cv::FileStorage::READ | cv::FileStorage::MEMORY);
std::vector<cv::KeyPoint> kv_read;
ASSERT_NO_THROW(fs_read["kv"] >> kv_read);
ASSERT_EQ(kv.size(), kv_read.size());
for (size_t i = 0; i < kv.size(); i++)
{
EXPECT_EQ(kv[i].pt, kv_read[i].pt);
EXPECT_EQ(kv[i].size, kv_read[i].size);
EXPECT_EQ(kv[i].angle, kv_read[i].angle);
EXPECT_EQ(kv[i].response, kv_read[i].response);
EXPECT_EQ(kv[i].octave, kv_read[i].octave);
EXPECT_EQ(kv[i].class_id, kv_read[i].class_id);
}
}
#endif
TEST(Core_InputOutput, FileStorage_format_xml) TEST(Core_InputOutput, FileStorage_format_xml)
{ {
FileStorage fs; FileStorage fs;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment