Move FileStorage to separate header

pull/747/head
Andrey Kamaev 12 years ago
parent 517062039e
commit 7193a73ca0
  1. 439
      modules/core/include/opencv2/core.hpp
  2. 1
      modules/core/include/opencv2/core/base.hpp
  3. 481
      modules/core/include/opencv2/core/operations.hpp
  4. 815
      modules/core/include/opencv2/core/persistence.hpp
  5. 4
      modules/core/include/opencv2/core/private.hpp
  6. 4
      modules/core/include/opencv2/core/types_c.h
  7. 2
      modules/core/src/algorithm.cpp
  8. 31
      modules/core/src/persistence.cpp
  9. 2
      modules/core/test/test_precomp.hpp
  10. 12
      modules/legacy/src/planardetect.cpp
  11. 2
      modules/python/CMakeLists.txt

@ -49,19 +49,13 @@
#include "opencv2/core/cvdef.h"
#include "opencv2/core/version.hpp"
// Used by FileStorage
typedef struct CvFileStorage CvFileStorage;
struct CvFileNode;
struct CvSeq;
struct CvSeqBlock;
#include "opencv2/core/base.hpp"
#include "opencv2/core/cvstd.hpp"
#include "opencv2/core/traits.hpp"
#include "opencv2/core/matx.hpp"
#include "opencv2/core/types.hpp"
#include "opencv2/core/mat.hpp"
#include "opencv2/core/persistence.hpp"
#ifndef SKIP_INCLUDES
#include <limits.h>
@ -127,78 +121,6 @@ public:
CV_EXPORTS void error( const Exception& exc );
CV_EXPORTS void scalarToRawData(const Scalar& s, void* buf, int type, int unroll_to=0);
/*!
Random Number Generator
The class implements RNG using Multiply-with-Carry algorithm
*/
class CV_EXPORTS RNG
{
public:
enum { UNIFORM = 0, NORMAL = 1 };
RNG();
RNG(uint64 state);
//! updates the state and returns the next 32-bit unsigned integer random number
unsigned next();
operator uchar();
operator schar();
operator ushort();
operator short();
operator unsigned();
//! returns a random integer sampled uniformly from [0, N).
unsigned operator ()(unsigned N);
unsigned operator ()();
operator int();
operator float();
operator double();
//! returns uniformly distributed integer random number from [a,b) range
int uniform(int a, int b);
//! returns uniformly distributed floating-point random number from [a,b) range
float uniform(float a, float b);
//! returns uniformly distributed double-precision floating-point random number from [a,b) range
double uniform(double a, double b);
void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange = false );
//! returns Gaussian random variate with mean zero.
double gaussian(double sigma);
uint64 state;
};
class CV_EXPORTS RNG_MT19937
{
public:
RNG_MT19937();
RNG_MT19937(unsigned s);
void seed(unsigned s);
unsigned next();
operator int();
operator unsigned();
operator float();
operator double();
unsigned operator ()(unsigned N);
unsigned operator ()();
// returns uniformly distributed integer random number from [a,b) range
int uniform(int a, int b);
// returns uniformly distributed floating-point random number from [a,b) range
float uniform(float a, float b);
// returns uniformly distributed double-precision floating-point random number from [a,b) range
double uniform(double a, double b);
private:
enum PeriodParameters {N = 624, M = 397};
unsigned state[N];
int mti;
};
typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
const uchar* src2, size_t step2,
uchar* dst, size_t step, Size sz,
@ -958,331 +880,78 @@ public:
//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
class CV_EXPORTS FileNode;
/*!
XML/YAML File Storage Class.
The class describes an object associated with XML or YAML file.
It can be used to store data to such a file or read and decode the data.
The storage is organized as a tree of nested sequences (or lists) and mappings.
Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator.
Mapping is analogue of std::map or C structure, which elements are accessed by names.
The most top level structure is a mapping.
Leaves of the file storage tree are integers, floating-point numbers and text strings.
For example, the following code:
\code
// open file storage for writing. Type of the file is determined from the extension
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH";
fs << "test_mat" << Mat::eye(3,3,CV_32F);
fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
"{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
fs << "]" << "}";
\endcode
will produce the following file:
\verbatim
%YAML:1.0
test_int: 5
test_real: 3.1000000000000001e+00
test_string: ABCDEFGH
test_mat: !!opencv-matrix
rows: 3
cols: 3
dt: f
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ]
test_list:
- 1.0000000000000000e-13
- 2
- 3.1415926535897931e+00
- -3435345
- "2-502 2-029 3egegeg"
- { month:12, day:31, year:1969 }
test_map:
x: 1
y: 2
width: 100
height: 200
lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ]
\endverbatim
and to read the file above, the following code can be used:
Random Number Generator
\code
// open file storage for reading.
// Type of the file is determined from the content, not the extension
FileStorage fs("test.yml", FileStorage::READ);
int test_int = (int)fs["test_int"];
double test_real = (double)fs["test_real"];
String test_string = (String)fs["test_string"];
Mat M;
fs["test_mat"] >> M;
FileNode tl = fs["test_list"];
CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6);
double tl0 = (double)tl[0];
int tl1 = (int)tl[1];
double tl2 = (double)tl[2];
int tl3 = (int)tl[3];
String tl4 = (String)tl[4];
CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3);
int month = (int)tl[5]["month"];
int day = (int)tl[5]["day"];
int year = (int)tl[5]["year"];
FileNode tm = fs["test_map"];
int x = (int)tm["x"];
int y = (int)tm["y"];
int width = (int)tm["width"];
int height = (int)tm["height"];
int lbp_val = 0;
FileNodeIterator it = tm["lbp"].begin();
for(int k = 0; k < 8; k++, ++it)
lbp_val |= ((int)*it) << k;
\endcode
The class implements RNG using Multiply-with-Carry algorithm
*/
class CV_EXPORTS_W FileStorage
class CV_EXPORTS RNG
{
public:
//! file storage mode
enum
{
READ=0, //! read mode
WRITE=1, //! write mode
APPEND=2, //! append mode
MEMORY=4,
FORMAT_MASK=(7<<3),
FORMAT_AUTO=0,
FORMAT_XML=(1<<3),
FORMAT_YAML=(2<<3)
};
enum
{
UNDEFINED=0,
VALUE_EXPECTED=1,
NAME_EXPECTED=2,
INSIDE_MAP=4
};
//! the default constructor
CV_WRAP FileStorage();
//! the full constructor that opens file storage for reading or writing
CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());
//! the constructor that takes pointer to the C FileStorage structure
FileStorage(CvFileStorage* fs);
//! the destructor. calls release()
virtual ~FileStorage();
//! opens file storage for reading or writing. The previous storage is closed with release()
CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());
//! returns true if the object is associated with currently opened file.
CV_WRAP virtual bool isOpened() const;
//! closes the file and releases all the memory buffers
CV_WRAP virtual void release();
//! closes the file, releases all the memory buffers and returns the text string
CV_WRAP virtual String releaseAndGetString();
//! returns the first element of the top-level mapping
CV_WRAP FileNode getFirstTopLevelNode() const;
//! returns the top-level mapping. YAML supports multiple streams
CV_WRAP FileNode root(int streamidx=0) const;
//! returns the specified element of the top-level mapping
FileNode operator[](const String& nodename) const;
//! returns the specified element of the top-level mapping
CV_WRAP FileNode operator[](const char* nodename) const;
//! returns pointer to the underlying C FileStorage structure
CvFileStorage* operator *() { return fs; }
//! returns pointer to the underlying C FileStorage structure
const CvFileStorage* operator *() const { return fs; }
//! writes one or more numbers of the specified format to the currently written structure
void writeRaw( const String& fmt, const uchar* vec, size_t len );
//! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite()
void writeObj( const String& name, const void* obj );
//! returns the normalized object name for the specified file name
static String getDefaultObjectName(const String& filename);
Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
String elname; //!< the currently written element
std::vector<char> structs; //!< the stack of written structures
int state; //!< the writer state
};
enum { UNIFORM = 0, NORMAL = 1 };
class CV_EXPORTS FileNodeIterator;
RNG();
RNG(uint64 state);
//! updates the state and returns the next 32-bit unsigned integer random number
unsigned next();
/*!
File Storage Node class
operator uchar();
operator schar();
operator ushort();
operator short();
operator unsigned();
//! returns a random integer sampled uniformly from [0, N).
unsigned operator ()(unsigned N);
unsigned operator ()();
operator int();
operator float();
operator double();
//! returns uniformly distributed integer random number from [a,b) range
int uniform(int a, int b);
//! returns uniformly distributed floating-point random number from [a,b) range
float uniform(float a, float b);
//! returns uniformly distributed double-precision floating-point random number from [a,b) range
double uniform(double a, double b);
void fill( InputOutputArray mat, int distType, InputArray a, InputArray b, bool saturateRange = false );
//! returns Gaussian random variate with mean zero.
double gaussian(double sigma);
The node is used to store each and every element of the file storage opened for reading -
from the primitive objects, such as numbers and text strings, to the complex nodes:
sequences, mappings and the registered objects.
uint64 state;
};
Note that file nodes are only used for navigating file storages opened for reading.
When a file storage is opened for writing, no data is stored in memory after it is written.
*/
class CV_EXPORTS_W_SIMPLE FileNode
class CV_EXPORTS RNG_MT19937
{
public:
//! type of the file storage node
enum
{
NONE=0, //!< empty node
INT=1, //!< an integer
REAL=2, //!< floating-point number
FLOAT=REAL, //!< synonym or REAL
STR=3, //!< text string in UTF-8 encoding
STRING=STR, //!< synonym for STR
REF=4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
SEQ=5, //!< sequence
MAP=6, //!< mapping
TYPE_MASK=7,
FLOW=8, //!< compact representation of a sequence or mapping. Used only by YAML writer
USER=16, //!< a registered object (e.g. a matrix)
EMPTY=32, //!< empty structure (sequence or mapping)
NAMED=64 //!< the node has a name (i.e. it is element of a mapping)
};
//! the default constructor
CV_WRAP FileNode();
//! the full constructor wrapping CvFileNode structure.
FileNode(const CvFileStorage* fs, const CvFileNode* node);
//! the copy constructor
FileNode(const FileNode& node);
//! returns element of a mapping node
FileNode operator[](const String& nodename) const;
//! returns element of a mapping node
CV_WRAP FileNode operator[](const char* nodename) const;
//! returns element of a sequence node
CV_WRAP FileNode operator[](int i) const;
//! returns type of the node
CV_WRAP int type() const;
//! returns true if the node is empty
CV_WRAP bool empty() const;
//! returns true if the node is a "none" object
CV_WRAP bool isNone() const;
//! returns true if the node is a sequence
CV_WRAP bool isSeq() const;
//! returns true if the node is a mapping
CV_WRAP bool isMap() const;
//! returns true if the node is an integer
CV_WRAP bool isInt() const;
//! returns true if the node is a floating-point number
CV_WRAP bool isReal() const;
//! returns true if the node is a text string
CV_WRAP bool isString() const;
//! returns true if the node has a name
CV_WRAP bool isNamed() const;
//! returns the node name or an empty string if the node is nameless
CV_WRAP String name() const;
//! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
CV_WRAP size_t size() const;
//! returns the node content as an integer. If the node stores floating-point number, it is rounded.
operator int() const;
//! returns the node content as float
operator float() const;
//! returns the node content as double
operator double() const;
//! returns the node content as text string
operator String() const;
#ifndef OPENCV_NOSTL
operator std::string() const;
#endif
RNG_MT19937();
RNG_MT19937(unsigned s);
void seed(unsigned s);
//! returns pointer to the underlying file node
CvFileNode* operator *();
//! returns pointer to the underlying file node
const CvFileNode* operator* () const;
unsigned next();
//! returns iterator pointing to the first node element
FileNodeIterator begin() const;
//! returns iterator pointing to the element following the last node element
FileNodeIterator end() const;
operator int();
operator unsigned();
operator float();
operator double();
//! reads node elements to the buffer with the specified format
void readRaw( const String& fmt, uchar* vec, size_t len ) const;
//! reads the registered object and returns pointer to it
void* readObj() const;
unsigned operator ()(unsigned N);
unsigned operator ()();
// do not use wrapper pointer classes for better efficiency
const CvFileStorage* fs;
const CvFileNode* node;
};
// returns uniformly distributed integer random number from [a,b) range
int uniform(int a, int b);
// returns uniformly distributed floating-point random number from [a,b) range
float uniform(float a, float b);
// returns uniformly distributed double-precision floating-point random number from [a,b) range
double uniform(double a, double b);
private:
enum PeriodParameters {N = 624, M = 397};
unsigned state[N];
int mti;
};
/*!
File Node Iterator
The class is used for iterating sequences (usually) and mappings.
*/
class CV_EXPORTS FileNodeIterator
{
public:
//! the default constructor
FileNodeIterator();
//! the full constructor set to the ofs-th element of the node
FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
//! the copy constructor
FileNodeIterator(const FileNodeIterator& it);
//! returns the currently observed element
FileNode operator *() const;
//! accesses the currently observed element methods
FileNode operator ->() const;
//! moves iterator to the next node
FileNodeIterator& operator ++ ();
//! moves iterator to the next node
FileNodeIterator operator ++ (int);
//! moves iterator to the previous node
FileNodeIterator& operator -- ();
//! moves iterator to the previous node
FileNodeIterator operator -- (int);
//! moves iterator forward by the specified offset (possibly negative)
FileNodeIterator& operator += (int ofs);
//! moves iterator backward by the specified offset (possibly negative)
FileNodeIterator& operator -= (int ofs);
//! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format
FileNodeIterator& readRaw( const String& fmt, uchar* vec,
size_t maxCount=(size_t)INT_MAX );
struct SeqReader
{
int header_size;
CvSeq* seq; /* sequence, beign read */
CvSeqBlock* block; /* current block */
schar* ptr; /* pointer to element be read next */
schar* block_min; /* pointer to the beginning of block */
schar* block_max; /* pointer to the end of block */
int delta_index;/* = seq->first->start_index */
schar* prev_elem; /* pointer to previous element */
};
const CvFileStorage* fs;
const CvFileNode* container;
SeqReader reader;
size_t remaining;
};
//////////////////////////////////////// Algorithm ////////////////////////////////////
class CV_EXPORTS Algorithm;
class CV_EXPORTS AlgorithmInfo;

@ -449,6 +449,7 @@ class CV_EXPORTS Range;
class CV_EXPORTS TermCriteria;
class CV_EXPORTS KeyPoint;
class CV_EXPORTS DMatch;
class CV_EXPORTS RNG;
class CV_EXPORTS Mat;
class CV_EXPORTS MatExpr;

@ -52,21 +52,17 @@
#include <limits.h>
#endif // SKIP_INCLUDES
#include <limits>
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable:4127) //conditional expression is constant
#endif
namespace cv
{
////////////////////////////// Matx methods depending on core API /////////////////////////////
namespace internal
{
template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
template<typename _Tp, int m> struct Matx_FastInvOp
{
bool operator()(const Matx<_Tp, m, m>& a, Matx<_Tp, m, m>& b, int method) const
{
@ -83,7 +79,7 @@ template<typename _Tp, int m> struct CV_EXPORTS Matx_FastInvOp
}
};
template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
template<typename _Tp> struct Matx_FastInvOp<_Tp, 2>
{
bool operator()(const Matx<_Tp, 2, 2>& a, Matx<_Tp, 2, 2>& b, int) const
{
@ -99,7 +95,7 @@ template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 2>
}
};
template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
template<typename _Tp> struct Matx_FastInvOp<_Tp, 3>
{
bool operator()(const Matx<_Tp, 3, 3>& a, Matx<_Tp, 3, 3>& b, int) const
{
@ -123,7 +119,7 @@ template<typename _Tp> struct CV_EXPORTS Matx_FastInvOp<_Tp, 3>
};
template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
template<typename _Tp, int m, int n> struct Matx_FastSolveOp
{
bool operator()(const Matx<_Tp, m, m>& a, const Matx<_Tp, m, n>& b,
Matx<_Tp, m, n>& x, int method) const
@ -137,7 +133,7 @@ template<typename _Tp, int m, int n> struct CV_EXPORTS Matx_FastSolveOp
}
};
template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
template<typename _Tp> struct Matx_FastSolveOp<_Tp, 2, 1>
{
bool operator()(const Matx<_Tp, 2, 2>& a, const Matx<_Tp, 2, 1>& b,
Matx<_Tp, 2, 1>& x, int) const
@ -152,7 +148,7 @@ template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 2, 1>
}
};
template<typename _Tp> struct CV_EXPORTS Matx_FastSolveOp<_Tp, 3, 1>
template<typename _Tp> struct Matx_FastSolveOp<_Tp, 3, 1>
{
bool operator()(const Matx<_Tp, 3, 3>& a, const Matx<_Tp, 3, 1>& b,
Matx<_Tp, 3, 1>& x, int) const
@ -227,7 +223,7 @@ Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) c
////////////////////////////// Augmenting algebraic & logical operations //////////////////////////////////
////////////////////////// Augmenting algebraic & logical operations //////////////////////////
#define CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
static inline A& operator op (A& a, const B& b) { cvop; return a; }
@ -288,7 +284,7 @@ CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
///////////////////////////////////////////// SVD /////////////////////////////////////////////
inline SVD::SVD() {}
inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
@ -330,7 +326,10 @@ SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
CV_Assert(_dst.data == (uchar*)&dst.val[0]);
}
// Multiply-with-Carry RNG
/////////////////////////////////// Multiply-with-Carry RNG ///////////////////////////////////
inline RNG::RNG() { state = 0xffffffff; }
inline RNG::RNG(uint64 _state) { state = _state ? _state : 0xffffffff; }
@ -356,21 +355,34 @@ inline unsigned RNG::next()
return (unsigned)state;
}
inline uchar* LineIterator::operator *() { return ptr; }
inline LineIterator& LineIterator::operator ++()
///////////////////////////////////////// LineIterator ////////////////////////////////////////
inline
uchar* LineIterator::operator *()
{
return ptr;
}
inline
LineIterator& LineIterator::operator ++()
{
int mask = err < 0 ? -1 : 0;
err += minusDelta + (plusDelta & mask);
ptr += minusStep + (plusStep & mask);
return *this;
}
inline LineIterator LineIterator::operator ++(int)
inline
LineIterator LineIterator::operator ++(int)
{
LineIterator it = *this;
++(*this);
return it;
}
inline Point LineIterator::pos() const
inline
Point LineIterator::pos() const
{
Point p;
p.y = (int)((ptr - ptr0)/step);
@ -378,6 +390,7 @@ inline Point LineIterator::pos() const
return p;
}
//! returns the next unifomly-distributed random number of the specified type
template<typename _Tp> static inline _Tp randu()
{
@ -385,429 +398,6 @@ template<typename _Tp> static inline _Tp randu()
}
//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
CV_EXPORTS_W void write( FileStorage& fs, const String& name, int value );
CV_EXPORTS_W void write( FileStorage& fs, const String& name, float value );
CV_EXPORTS_W void write( FileStorage& fs, const String& name, double value );
CV_EXPORTS_W void write( FileStorage& fs, const String& name, const String& value );
template<typename _Tp> inline void write(FileStorage& fs, const _Tp& value)
{ write(fs, String(), value); }
CV_EXPORTS void writeScalar( FileStorage& fs, int value );
CV_EXPORTS void writeScalar( FileStorage& fs, float value );
CV_EXPORTS void writeScalar( FileStorage& fs, double value );
CV_EXPORTS void writeScalar( FileStorage& fs, const String& value );
template<> inline void write( FileStorage& fs, const int& value )
{
writeScalar(fs, value);
}
template<> inline void write( FileStorage& fs, const float& value )
{
writeScalar(fs, value);
}
template<> inline void write( FileStorage& fs, const double& value )
{
writeScalar(fs, value);
}
template<> inline void write( FileStorage& fs, const String& value )
{
writeScalar(fs, value);
}
template<typename _Tp> inline void write(FileStorage& fs, const Point_<_Tp>& pt )
{
write(fs, pt.x);
write(fs, pt.y);
}
template<typename _Tp> inline void write(FileStorage& fs, const Point3_<_Tp>& pt )
{
write(fs, pt.x);
write(fs, pt.y);
write(fs, pt.z);
}
template<typename _Tp> inline void write(FileStorage& fs, const Size_<_Tp>& sz )
{
write(fs, sz.width);
write(fs, sz.height);
}
template<typename _Tp> inline void write(FileStorage& fs, const Complex<_Tp>& c )
{
write(fs, c.re);
write(fs, c.im);
}
template<typename _Tp> inline void write(FileStorage& fs, const Rect_<_Tp>& r )
{
write(fs, r.x);
write(fs, r.y);
write(fs, r.width);
write(fs, r.height);
}
template<typename _Tp, int cn> inline void write(FileStorage& fs, const Vec<_Tp, cn>& v )
{
for(int i = 0; i < cn; i++)
write(fs, v.val[i]);
}
template<typename _Tp> inline void write(FileStorage& fs, const Scalar_<_Tp>& s )
{
write(fs, s.val[0]);
write(fs, s.val[1]);
write(fs, s.val[2]);
write(fs, s.val[3]);
}
inline void write(FileStorage& fs, const Range& r )
{
write(fs, r.start);
write(fs, r.end);
}
class CV_EXPORTS WriteStructContext
{
public:
WriteStructContext(FileStorage& _fs, const String& name,
int flags, const String& typeName=String());
~WriteStructContext();
FileStorage* fs;
};
template<typename _Tp> inline void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, pt.x);
write(fs, pt.y);
}
template<typename _Tp> inline void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, pt.x);
write(fs, pt.y);
write(fs, pt.z);
}
template<typename _Tp> inline void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, sz.width);
write(fs, sz.height);
}
template<typename _Tp> inline void write(FileStorage& fs, const String& name, const Complex<_Tp>& c )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, c.re);
write(fs, c.im);
}
template<typename _Tp> inline void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, r.x);
write(fs, r.y);
write(fs, r.width);
write(fs, r.height);
}
template<typename _Tp, int cn> inline void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
for(int i = 0; i < cn; i++)
write(fs, v.val[i]);
}
template<typename _Tp> inline void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, s.val[0]);
write(fs, s.val[1]);
write(fs, s.val[2]);
write(fs, s.val[3]);
}
inline void write(FileStorage& fs, const String& name, const Range& r )
{
WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, r.start);
write(fs, r.end);
}
template<typename _Tp, int numflag> class CV_EXPORTS VecWriterProxy
{
public:
VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
void operator()(const std::vector<_Tp>& vec) const
{
size_t i, count = vec.size();
for( i = 0; i < count; i++ )
write( *fs, vec[i] );
}
FileStorage* fs;
};
template<typename _Tp> class CV_EXPORTS VecWriterProxy<_Tp,1>
{
public:
VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
void operator()(const std::vector<_Tp>& vec) const
{
int _fmt = DataType<_Tp>::fmt;
char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
fs->writeRaw( String(fmt), !vec.empty() ? (uchar*)&vec[0] : 0, vec.size()*sizeof(_Tp) );
}
FileStorage* fs;
};
template<typename _Tp> static inline void write( FileStorage& fs, const std::vector<_Tp>& vec )
{
VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
w(vec);
}
template<typename _Tp> static inline void write( FileStorage& fs, const String& name,
const std::vector<_Tp>& vec )
{
WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
write(fs, vec);
}
CV_EXPORTS_W void write( FileStorage& fs, const String& name, const Mat& value );
CV_EXPORTS void write( FileStorage& fs, const String& name, const SparseMat& value );
template<typename _Tp> static inline FileStorage& operator << (FileStorage& fs, const _Tp& value)
{
if( !fs.isOpened() )
return fs;
if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
CV_Error( Error::StsError, "No element name has been given" );
write( fs, fs.elname, value );
if( fs.state & FileStorage::INSIDE_MAP )
fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
return fs;
}
CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str);
static inline FileStorage& operator << (FileStorage& fs, const char* str)
{ return (fs << String(str)); }
static inline FileStorage& operator << (FileStorage& fs, char* value)
{ return (fs << String(value)); }
inline FileNode::FileNode() : fs(0), node(0) {}
inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node)
: fs(_fs), node(_node) {}
inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
inline bool FileNode::empty() const { return node == 0; }
inline bool FileNode::isNone() const { return type() == NONE; }
inline bool FileNode::isSeq() const { return type() == SEQ; }
inline bool FileNode::isMap() const { return type() == MAP; }
inline bool FileNode::isInt() const { return type() == INT; }
inline bool FileNode::isReal() const { return type() == REAL; }
inline bool FileNode::isString() const { return type() == STR; }
inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
inline const CvFileNode* FileNode::operator* () const { return node; }
CV_EXPORTS void read(const FileNode& node, int& value, int default_value);
CV_EXPORTS void read(const FileNode& node, float& value, float default_value);
CV_EXPORTS void read(const FileNode& node, double& value, double default_value);
CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value);
CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat=SparseMat() );
CV_EXPORTS_W void read(const FileNode& node, Mat& mat, const Mat& default_mat=Mat() );
CV_EXPORTS void read(const FileNode& node, std::vector<KeyPoint>& keypoints);
CV_EXPORTS void write(FileStorage& fs, const String& objname, const std::vector<KeyPoint>& keypoints);
static inline void read(const FileNode& node, bool& value, bool default_value)
{
int temp; read(node, temp, (int)default_value);
value = temp != 0;
}
static inline void read(const FileNode& node, uchar& value, uchar default_value)
{
int temp; read(node, temp, (int)default_value);
value = saturate_cast<uchar>(temp);
}
static inline void read(const FileNode& node, schar& value, schar default_value)
{
int temp; read(node, temp, (int)default_value);
value = saturate_cast<schar>(temp);
}
static inline void read(const FileNode& node, ushort& value, ushort default_value)
{
int temp; read(node, temp, (int)default_value);
value = saturate_cast<ushort>(temp);
}
static inline void read(const FileNode& node, short& value, short default_value)
{
int temp; read(node, temp, (int)default_value);
value = saturate_cast<short>(temp);
}
inline FileNode::operator int() const
{
int value;
read(*this, value, 0);
return value;
}
inline FileNode::operator float() const
{
float value;
read(*this, value, 0.f);
return value;
}
inline FileNode::operator double() const
{
double value;
read(*this, value, 0.);
return value;
}
inline FileNode::operator String() const
{
String value;
read(*this, value, value);
return value;
}
inline String::String(const FileNode& fn): cstr_(0), len_(0)
{
read(fn, *this, *this);
}
inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const
{
begin().readRaw( fmt, vec, len );
}
template<typename _Tp, int numflag> class CV_EXPORTS VecReaderProxy
{
public:
VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
void operator()(std::vector<_Tp>& vec, size_t count) const
{
count = std::min(count, it->remaining);
vec.resize(count);
for( size_t i = 0; i < count; i++, ++(*it) )
read(**it, vec[i], _Tp());
}
FileNodeIterator* it;
};
template<typename _Tp> class CV_EXPORTS VecReaderProxy<_Tp,1>
{
public:
VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
void operator()(std::vector<_Tp>& vec, size_t count) const
{
size_t remaining = it->remaining, cn = DataType<_Tp>::channels;
int _fmt = DataType<_Tp>::fmt;
char fmt[] = { (char)((_fmt>>8)+'1'), (char)_fmt, '\0' };
size_t remaining1 = remaining/cn;
count = count < remaining1 ? count : remaining1;
vec.resize(count);
it->readRaw( String(fmt), !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp) );
}
FileNodeIterator* it;
};
template<typename _Tp> static inline void
read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount=(size_t)INT_MAX )
{
VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
r(vec, maxCount);
}
template<typename _Tp> static inline void
read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value=std::vector<_Tp>() )
{
if(!node.node)
vec = default_value;
else
{
FileNodeIterator it = node.begin();
read( it, vec );
}
}
inline FileNodeIterator FileNode::begin() const
{
return FileNodeIterator(fs, node);
}
inline FileNodeIterator FileNode::end() const
{
return FileNodeIterator(fs, node, size());
}
inline FileNode FileNodeIterator::operator *() const
{ return FileNode(fs, (const CvFileNode*)reader.ptr); }
inline FileNode FileNodeIterator::operator ->() const
{ return FileNode(fs, (const CvFileNode*)reader.ptr); }
template<typename _Tp> static inline FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
{ read( *it, value, _Tp()); return ++it; }
template<typename _Tp> static inline
FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
{
VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
r(vec, (size_t)INT_MAX);
return it;
}
template<typename _Tp> static inline void operator >> (const FileNode& n, _Tp& value)
{ read( n, value, _Tp()); }
template<typename _Tp> static inline void operator >> (const FileNode& n, std::vector<_Tp>& vec)
{ FileNodeIterator it = n.begin(); it >> vec; }
static inline bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it1.fs == it2.fs && it1.container == it2.container &&
it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
}
static inline bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return !(it1 == it2);
}
static inline ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it2.remaining - it1.remaining;
}
static inline bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it1.remaining > it2.remaining;
}
inline FileNode FileStorage::getFirstTopLevelNode() const
{
FileNode r = root();
FileNodeIterator it = r.begin();
return it != r.end() ? *it : FileNode();
}
//////////////////////////////////////////////////////////////////////////////
class CV_EXPORTS Formatter
@ -959,6 +549,9 @@ template<typename _Tp> inline std::ostream& operator<<(std::ostream& out, const
}
////////////////////////////////////////// Algorithm //////////////////////////////////////////
template<typename _Tp> inline Ptr<_Tp> Algorithm::create(const String& name)
{
return _create(name).ptr<_Tp>();
@ -1030,8 +623,4 @@ template<typename _Tp> inline void AlgorithmInfo::addParam(Algorithm& algo, cons
}
#ifdef _MSC_VER
# pragma warning(pop)
#endif
#endif

@ -0,0 +1,815 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#ifndef __OPENCV_CORE_PERSISTENCE_HPP__
#define __OPENCV_CORE_PERSISTENCE_HPP__
#ifndef __cplusplus
# error persistence.hpp header must be compiled as C++
#endif
// black-box structures used by FileStorage
typedef struct CvFileStorage CvFileStorage;
typedef struct CvFileNode CvFileNode;
#include "opencv2/core/types.hpp"
#include "opencv2/core/mat.hpp"
namespace cv {
////////////////////////// XML & YAML I/O //////////////////////////
class CV_EXPORTS FileNode;
class CV_EXPORTS FileNodeIterator;
/*!
XML/YAML File Storage Class.
The class describes an object associated with XML or YAML file.
It can be used to store data to such a file or read and decode the data.
The storage is organized as a tree of nested sequences (or lists) and mappings.
Sequence is a heterogenious array, which elements are accessed by indices or sequentially using an iterator.
Mapping is analogue of std::map or C structure, which elements are accessed by names.
The most top level structure is a mapping.
Leaves of the file storage tree are integers, floating-point numbers and text strings.
For example, the following code:
\code
// open file storage for writing. Type of the file is determined from the extension
FileStorage fs("test.yml", FileStorage::WRITE);
fs << "test_int" << 5 << "test_real" << 3.1 << "test_string" << "ABCDEFGH";
fs << "test_mat" << Mat::eye(3,3,CV_32F);
fs << "test_list" << "[" << 0.0000000000001 << 2 << CV_PI << -3435345 << "2-502 2-029 3egegeg" <<
"{:" << "month" << 12 << "day" << 31 << "year" << 1969 << "}" << "]";
fs << "test_map" << "{" << "x" << 1 << "y" << 2 << "width" << 100 << "height" << 200 << "lbp" << "[:";
const uchar arr[] = {0, 1, 1, 0, 1, 1, 0, 1};
fs.writeRaw("u", arr, (int)(sizeof(arr)/sizeof(arr[0])));
fs << "]" << "}";
\endcode
will produce the following file:
\verbatim
%YAML:1.0
test_int: 5
test_real: 3.1000000000000001e+00
test_string: ABCDEFGH
test_mat: !!opencv-matrix
rows: 3
cols: 3
dt: f
data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1. ]
test_list:
- 1.0000000000000000e-13
- 2
- 3.1415926535897931e+00
- -3435345
- "2-502 2-029 3egegeg"
- { month:12, day:31, year:1969 }
test_map:
x: 1
y: 2
width: 100
height: 200
lbp: [ 0, 1, 1, 0, 1, 1, 0, 1 ]
\endverbatim
and to read the file above, the following code can be used:
\code
// open file storage for reading.
// Type of the file is determined from the content, not the extension
FileStorage fs("test.yml", FileStorage::READ);
int test_int = (int)fs["test_int"];
double test_real = (double)fs["test_real"];
String test_string = (String)fs["test_string"];
Mat M;
fs["test_mat"] >> M;
FileNode tl = fs["test_list"];
CV_Assert(tl.type() == FileNode::SEQ && tl.size() == 6);
double tl0 = (double)tl[0];
int tl1 = (int)tl[1];
double tl2 = (double)tl[2];
int tl3 = (int)tl[3];
String tl4 = (String)tl[4];
CV_Assert(tl[5].type() == FileNode::MAP && tl[5].size() == 3);
int month = (int)tl[5]["month"];
int day = (int)tl[5]["day"];
int year = (int)tl[5]["year"];
FileNode tm = fs["test_map"];
int x = (int)tm["x"];
int y = (int)tm["y"];
int width = (int)tm["width"];
int height = (int)tm["height"];
int lbp_val = 0;
FileNodeIterator it = tm["lbp"].begin();
for(int k = 0; k < 8; k++, ++it)
lbp_val |= ((int)*it) << k;
\endcode
*/
class CV_EXPORTS_W FileStorage
{
public:
//! file storage mode
enum
{
READ = 0, //! read mode
WRITE = 1, //! write mode
APPEND = 2, //! append mode
MEMORY = 4,
FORMAT_MASK = (7<<3),
FORMAT_AUTO = 0,
FORMAT_XML = (1<<3),
FORMAT_YAML = (2<<3)
};
enum
{
UNDEFINED = 0,
VALUE_EXPECTED = 1,
NAME_EXPECTED = 2,
INSIDE_MAP = 4
};
//! the default constructor
CV_WRAP FileStorage();
//! the full constructor that opens file storage for reading or writing
CV_WRAP FileStorage(const String& source, int flags, const String& encoding=String());
//! the constructor that takes pointer to the C FileStorage structure
FileStorage(CvFileStorage* fs);
//! the destructor. calls release()
virtual ~FileStorage();
//! opens file storage for reading or writing. The previous storage is closed with release()
CV_WRAP virtual bool open(const String& filename, int flags, const String& encoding=String());
//! returns true if the object is associated with currently opened file.
CV_WRAP virtual bool isOpened() const;
//! closes the file and releases all the memory buffers
CV_WRAP virtual void release();
//! closes the file, releases all the memory buffers and returns the text string
CV_WRAP virtual String releaseAndGetString();
//! returns the first element of the top-level mapping
CV_WRAP FileNode getFirstTopLevelNode() const;
//! returns the top-level mapping. YAML supports multiple streams
CV_WRAP FileNode root(int streamidx=0) const;
//! returns the specified element of the top-level mapping
FileNode operator[](const String& nodename) const;
//! returns the specified element of the top-level mapping
CV_WRAP FileNode operator[](const char* nodename) const;
//! returns pointer to the underlying C FileStorage structure
CvFileStorage* operator *() { return fs; }
//! returns pointer to the underlying C FileStorage structure
const CvFileStorage* operator *() const { return fs; }
//! writes one or more numbers of the specified format to the currently written structure
void writeRaw( const String& fmt, const uchar* vec, size_t len );
//! writes the registered C structure (CvMat, CvMatND, CvSeq). See cvWrite()
void writeObj( const String& name, const void* obj );
//! returns the normalized object name for the specified file name
static String getDefaultObjectName(const String& filename);
Ptr<CvFileStorage> fs; //!< the underlying C FileStorage structure
String elname; //!< the currently written element
std::vector<char> structs; //!< the stack of written structures
int state; //!< the writer state
};
/*!
File Storage Node class
The node is used to store each and every element of the file storage opened for reading -
from the primitive objects, such as numbers and text strings, to the complex nodes:
sequences, mappings and the registered objects.
Note that file nodes are only used for navigating file storages opened for reading.
When a file storage is opened for writing, no data is stored in memory after it is written.
*/
class CV_EXPORTS_W_SIMPLE FileNode
{
public:
//! type of the file storage node
enum
{
NONE = 0, //!< empty node
INT = 1, //!< an integer
REAL = 2, //!< floating-point number
FLOAT = REAL, //!< synonym or REAL
STR = 3, //!< text string in UTF-8 encoding
STRING = STR, //!< synonym for STR
REF = 4, //!< integer of size size_t. Typically used for storing complex dynamic structures where some elements reference the others
SEQ = 5, //!< sequence
MAP = 6, //!< mapping
TYPE_MASK = 7,
FLOW = 8, //!< compact representation of a sequence or mapping. Used only by YAML writer
USER = 16, //!< a registered object (e.g. a matrix)
EMPTY = 32, //!< empty structure (sequence or mapping)
NAMED = 64 //!< the node has a name (i.e. it is element of a mapping)
};
//! the default constructor
CV_WRAP FileNode();
//! the full constructor wrapping CvFileNode structure.
FileNode(const CvFileStorage* fs, const CvFileNode* node);
//! the copy constructor
FileNode(const FileNode& node);
//! returns element of a mapping node
FileNode operator[](const String& nodename) const;
//! returns element of a mapping node
CV_WRAP FileNode operator[](const char* nodename) const;
//! returns element of a sequence node
CV_WRAP FileNode operator[](int i) const;
//! returns type of the node
CV_WRAP int type() const;
//! returns true if the node is empty
CV_WRAP bool empty() const;
//! returns true if the node is a "none" object
CV_WRAP bool isNone() const;
//! returns true if the node is a sequence
CV_WRAP bool isSeq() const;
//! returns true if the node is a mapping
CV_WRAP bool isMap() const;
//! returns true if the node is an integer
CV_WRAP bool isInt() const;
//! returns true if the node is a floating-point number
CV_WRAP bool isReal() const;
//! returns true if the node is a text string
CV_WRAP bool isString() const;
//! returns true if the node has a name
CV_WRAP bool isNamed() const;
//! returns the node name or an empty string if the node is nameless
CV_WRAP String name() const;
//! returns the number of elements in the node, if it is a sequence or mapping, or 1 otherwise.
CV_WRAP size_t size() const;
//! returns the node content as an integer. If the node stores floating-point number, it is rounded.
operator int() const;
//! returns the node content as float
operator float() const;
//! returns the node content as double
operator double() const;
//! returns the node content as text string
operator String() const;
#ifndef OPENCV_NOSTL
operator std::string() const;
#endif
//! returns pointer to the underlying file node
CvFileNode* operator *();
//! returns pointer to the underlying file node
const CvFileNode* operator* () const;
//! returns iterator pointing to the first node element
FileNodeIterator begin() const;
//! returns iterator pointing to the element following the last node element
FileNodeIterator end() const;
//! reads node elements to the buffer with the specified format
void readRaw( const String& fmt, uchar* vec, size_t len ) const;
//! reads the registered object and returns pointer to it
void* readObj() const;
// do not use wrapper pointer classes for better efficiency
const CvFileStorage* fs;
const CvFileNode* node;
};
/*!
File Node Iterator
The class is used for iterating sequences (usually) and mappings.
*/
class CV_EXPORTS FileNodeIterator
{
public:
//! the default constructor
FileNodeIterator();
//! the full constructor set to the ofs-th element of the node
FileNodeIterator(const CvFileStorage* fs, const CvFileNode* node, size_t ofs=0);
//! the copy constructor
FileNodeIterator(const FileNodeIterator& it);
//! returns the currently observed element
FileNode operator *() const;
//! accesses the currently observed element methods
FileNode operator ->() const;
//! moves iterator to the next node
FileNodeIterator& operator ++ ();
//! moves iterator to the next node
FileNodeIterator operator ++ (int);
//! moves iterator to the previous node
FileNodeIterator& operator -- ();
//! moves iterator to the previous node
FileNodeIterator operator -- (int);
//! moves iterator forward by the specified offset (possibly negative)
FileNodeIterator& operator += (int ofs);
//! moves iterator backward by the specified offset (possibly negative)
FileNodeIterator& operator -= (int ofs);
//! reads the next maxCount elements (or less, if the sequence/mapping last element occurs earlier) to the buffer with the specified format
FileNodeIterator& readRaw( const String& fmt, uchar* vec,
size_t maxCount=(size_t)INT_MAX );
struct SeqReader
{
int header_size;
void* seq; /* sequence, beign read; CvSeq */
void* block; /* current block; CvSeqBlock */
schar* ptr; /* pointer to element be read next */
schar* block_min; /* pointer to the beginning of block */
schar* block_max; /* pointer to the end of block */
int delta_index;/* = seq->first->start_index */
schar* prev_elem; /* pointer to previous element */
};
const CvFileStorage* fs;
const CvFileNode* container;
SeqReader reader;
size_t remaining;
};
/////////////////// XML & YAML I/O implementation //////////////////
CV_EXPORTS void write( FileStorage& fs, const String& name, int value );
CV_EXPORTS void write( FileStorage& fs, const String& name, float value );
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 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<KeyPoint>& value);
CV_EXPORTS void writeScalar( FileStorage& fs, int value );
CV_EXPORTS void writeScalar( FileStorage& fs, float value );
CV_EXPORTS void writeScalar( FileStorage& fs, double value );
CV_EXPORTS void writeScalar( FileStorage& fs, const String& value );
CV_EXPORTS void read(const FileNode& node, int& value, int default_value);
CV_EXPORTS void read(const FileNode& node, float& value, float default_value);
CV_EXPORTS void read(const FileNode& node, double& value, double default_value);
CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value);
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<KeyPoint>& keypoints);
CV_EXPORTS FileStorage& operator << (FileStorage& fs, const String& str);
namespace internal
{
class CV_EXPORTS WriteStructContext
{
public:
WriteStructContext(FileStorage& _fs, const String& name, int flags, const String& typeName = String());
~WriteStructContext();
private:
FileStorage* fs;
};
template<typename _Tp, int numflag> class VecWriterProxy
{
public:
VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
void operator()(const std::vector<_Tp>& vec) const
{
size_t count = vec.size();
for (size_t i = 0; i < count; i++)
write(*fs, vec[i]);
}
private:
FileStorage* fs;
};
template<typename _Tp> class VecWriterProxy<_Tp, 1>
{
public:
VecWriterProxy( FileStorage* _fs ) : fs(_fs) {}
void operator()(const std::vector<_Tp>& vec) const
{
int _fmt = DataType<_Tp>::fmt;
char fmt[] = { (char)((_fmt >> 8) + '1'), (char)_fmt, '\0' };
fs->writeRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, vec.size() * sizeof(_Tp));
}
private:
FileStorage* fs;
};
template<typename _Tp, int numflag> class VecReaderProxy
{
public:
VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
void operator()(std::vector<_Tp>& vec, size_t count) const
{
count = std::min(count, it->remaining);
vec.resize(count);
for (size_t i = 0; i < count; i++, ++(*it))
read(**it, vec[i], _Tp());
}
private:
FileNodeIterator* it;
};
template<typename _Tp> class VecReaderProxy<_Tp, 1>
{
public:
VecReaderProxy( FileNodeIterator* _it ) : it(_it) {}
void operator()(std::vector<_Tp>& vec, size_t count) const
{
size_t remaining = it->remaining;
size_t cn = DataType<_Tp>::channels;
int _fmt = DataType<_Tp>::fmt;
char fmt[] = { (char)((_fmt >> 8)+'1'), (char)_fmt, '\0' };
size_t remaining1 = remaining / cn;
count = count < remaining1 ? count : remaining1;
vec.resize(count);
it->readRaw(fmt, !vec.empty() ? (uchar*)&vec[0] : 0, count*sizeof(_Tp));
}
private:
FileNodeIterator* it;
};
} // internal
template<typename _Tp> static inline
void write(FileStorage& fs, const _Tp& value)
{
write(fs, String(), value);
}
template<> inline
void write( FileStorage& fs, const int& value )
{
writeScalar(fs, value);
}
template<> inline
void write( FileStorage& fs, const float& value )
{
writeScalar(fs, value);
}
template<> inline
void write( FileStorage& fs, const double& value )
{
writeScalar(fs, value);
}
template<> inline
void write( FileStorage& fs, const String& value )
{
writeScalar(fs, value);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const Point_<_Tp>& pt )
{
write(fs, pt.x);
write(fs, pt.y);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const Point3_<_Tp>& pt )
{
write(fs, pt.x);
write(fs, pt.y);
write(fs, pt.z);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const Size_<_Tp>& sz )
{
write(fs, sz.width);
write(fs, sz.height);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const Complex<_Tp>& c )
{
write(fs, c.re);
write(fs, c.im);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const Rect_<_Tp>& r )
{
write(fs, r.x);
write(fs, r.y);
write(fs, r.width);
write(fs, r.height);
}
template<typename _Tp, int cn> static inline
void write(FileStorage& fs, const Vec<_Tp, cn>& v )
{
for(int i = 0; i < cn; i++)
write(fs, v.val[i]);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const Scalar_<_Tp>& s )
{
write(fs, s.val[0]);
write(fs, s.val[1]);
write(fs, s.val[2]);
write(fs, s.val[3]);
}
static inline
void write(FileStorage& fs, const Range& r )
{
write(fs, r.start);
write(fs, r.end);
}
template<typename _Tp> static inline
void write( FileStorage& fs, const std::vector<_Tp>& vec )
{
internal::VecWriterProxy<_Tp, DataType<_Tp>::fmt != 0> w(&fs);
w(vec);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const String& name, const Point_<_Tp>& pt )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, pt);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const String& name, const Point3_<_Tp>& pt )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, pt);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const String& name, const Size_<_Tp>& sz )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, sz);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const String& name, const Complex<_Tp>& c )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, c);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const String& name, const Rect_<_Tp>& r )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, r);
}
template<typename _Tp, int cn> static inline
void write(FileStorage& fs, const String& name, const Vec<_Tp, cn>& v )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, v);
}
template<typename _Tp> static inline
void write(FileStorage& fs, const String& name, const Scalar_<_Tp>& s )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, s);
}
static inline
void write(FileStorage& fs, const String& name, const Range& r )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+FileNode::FLOW);
write(fs, r);
}
template<typename _Tp> static inline
void write( FileStorage& fs, const String& name, const std::vector<_Tp>& vec )
{
internal::WriteStructContext ws(fs, name, FileNode::SEQ+(DataType<_Tp>::fmt != 0 ? FileNode::FLOW : 0));
write(fs, vec);
}
static inline
void read(const FileNode& node, bool& value, bool default_value)
{
int temp;
read(node, temp, (int)default_value);
value = temp != 0;
}
static inline
void read(const FileNode& node, uchar& value, uchar default_value)
{
int temp;
read(node, temp, (int)default_value);
value = saturate_cast<uchar>(temp);
}
static inline
void read(const FileNode& node, schar& value, schar default_value)
{
int temp;
read(node, temp, (int)default_value);
value = saturate_cast<schar>(temp);
}
static inline
void read(const FileNode& node, ushort& value, ushort default_value)
{
int temp;
read(node, temp, (int)default_value);
value = saturate_cast<ushort>(temp);
}
static inline
void read(const FileNode& node, short& value, short default_value)
{
int temp;
read(node, temp, (int)default_value);
value = saturate_cast<short>(temp);
}
template<typename _Tp> static inline
void read( FileNodeIterator& it, std::vector<_Tp>& vec, size_t maxCount = (size_t)INT_MAX )
{
internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
r(vec, maxCount);
}
template<typename _Tp> static inline
void read( const FileNode& node, std::vector<_Tp>& vec, const std::vector<_Tp>& default_value = std::vector<_Tp>() )
{
if(!node.node)
vec = default_value;
else
{
FileNodeIterator it = node.begin();
read( it, vec );
}
}
template<typename _Tp> static inline
FileStorage& operator << (FileStorage& fs, const _Tp& value)
{
if( !fs.isOpened() )
return fs;
if( fs.state == FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP )
CV_Error( Error::StsError, "No element name has been given" );
write( fs, fs.elname, value );
if( fs.state & FileStorage::INSIDE_MAP )
fs.state = FileStorage::NAME_EXPECTED + FileStorage::INSIDE_MAP;
return fs;
}
static inline
FileStorage& operator << (FileStorage& fs, const char* str)
{
return (fs << String(str));
}
static inline
FileStorage& operator << (FileStorage& fs, char* value)
{
return (fs << String(value));
}
template<typename _Tp> static inline
FileNodeIterator& operator >> (FileNodeIterator& it, _Tp& value)
{
read( *it, value, _Tp());
return ++it;
}
template<typename _Tp> static inline
FileNodeIterator& operator >> (FileNodeIterator& it, std::vector<_Tp>& vec)
{
internal::VecReaderProxy<_Tp, DataType<_Tp>::fmt != 0> r(&it);
r(vec, (size_t)INT_MAX);
return it;
}
template<typename _Tp> static inline
void operator >> (const FileNode& n, _Tp& value)
{
read( n, value, _Tp());
}
template<typename _Tp> static inline
void operator >> (const FileNode& n, std::vector<_Tp>& vec)
{
FileNodeIterator it = n.begin();
it >> vec;
}
static inline
bool operator == (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it1.fs == it2.fs && it1.container == it2.container &&
it1.reader.ptr == it2.reader.ptr && it1.remaining == it2.remaining;
}
static inline
bool operator != (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return !(it1 == it2);
}
static inline
ptrdiff_t operator - (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it2.remaining - it1.remaining;
}
static inline
bool operator < (const FileNodeIterator& it1, const FileNodeIterator& it2)
{
return it1.remaining > it2.remaining;
}
inline FileNode FileStorage::getFirstTopLevelNode() const { FileNode r = root(); FileNodeIterator it = r.begin(); return it != r.end() ? *it : FileNode(); }
inline FileNode::FileNode() : fs(0), node(0) {}
inline FileNode::FileNode(const CvFileStorage* _fs, const CvFileNode* _node) : fs(_fs), node(_node) {}
inline FileNode::FileNode(const FileNode& _node) : fs(_node.fs), node(_node.node) {}
inline bool FileNode::empty() const { return node == 0; }
inline bool FileNode::isNone() const { return type() == NONE; }
inline bool FileNode::isSeq() const { return type() == SEQ; }
inline bool FileNode::isMap() const { return type() == MAP; }
inline bool FileNode::isInt() const { return type() == INT; }
inline bool FileNode::isReal() const { return type() == REAL; }
inline bool FileNode::isString() const { return type() == STR; }
inline CvFileNode* FileNode::operator *() { return (CvFileNode*)node; }
inline const CvFileNode* FileNode::operator* () const { return node; }
inline FileNode::operator int() const { int value; read(*this, value, 0); return value; }
inline FileNode::operator float() const { float value; read(*this, value, 0.f); return value; }
inline FileNode::operator double() const { double value; read(*this, value, 0.); return value; }
inline FileNode::operator String() const { String value; read(*this, value, value); return value; }
inline FileNodeIterator FileNode::begin() const { return FileNodeIterator(fs, node); }
inline FileNodeIterator FileNode::end() const { return FileNodeIterator(fs, node, size()); }
inline void FileNode::readRaw( const String& fmt, uchar* vec, size_t len ) const { begin().readRaw( fmt, vec, len ); }
inline FileNode FileNodeIterator::operator *() const { return FileNode(fs, (const CvFileNode*)reader.ptr); }
inline FileNode FileNodeIterator::operator ->() const { return FileNode(fs, (const CvFileNode*)reader.ptr); }
inline String::String(const FileNode& fn): cstr_(0), len_(0) { read(fn, *this, *this); }
} // cv
#endif // __OPENCV_CORE_PERSISTENCE_HPP__

@ -188,6 +188,10 @@ static inline cv::Size cvGetMatSize( const CvMat* mat )
return cv::Size(mat->cols, mat->rows);
}
namespace cv
{
CV_EXPORTS void scalarToRawData(const cv::Scalar& s, void* buf, int type, int unroll_to = 0);
}
/****************************************************************************************\

@ -1461,15 +1461,11 @@ CvSeqWriter;
int delta_index;/* = seq->first->start_index */ \
schar* prev_elem; /* pointer to previous element */
#ifdef __cplusplus
typedef cv::FileNodeIterator::SeqReader CvSeqReader;
#else
typedef struct CvSeqReader
{
CV_SEQ_READER_FIELDS()
}
CvSeqReader;
#endif
/****************************************************************************************/
/* Operations on sequences */

@ -423,7 +423,7 @@ void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
cv::write(fs, pname, algo->get<std::vector<Mat> >(pname));
else if( p.type == Param::ALGORITHM )
{
WriteStructContext ws(fs, pname, CV_NODE_MAP);
internal::WriteStructContext ws(fs, pname, CV_NODE_MAP);
Ptr<Algorithm> nestedAlgo = algo->get<Algorithm>(pname);
nestedAlgo->write(fs);
}

@ -5317,7 +5317,7 @@ FileNodeIterator::FileNodeIterator(const CvFileStorage* _fs,
container = _node;
if( !(_node->tag & FileNode::USER) && (node_type == FileNode::SEQ || node_type == FileNode::MAP) )
{
cvStartReadSeq( _node->data.seq, &reader );
cvStartReadSeq( _node->data.seq, (CvSeqReader*)&reader );
remaining = FileNode(_fs, _node).size();
}
else
@ -5350,7 +5350,12 @@ FileNodeIterator& FileNodeIterator::operator ++()
if( remaining > 0 )
{
if( reader.seq )
CV_NEXT_SEQ_ELEM( reader.seq->elem_size, reader );
{
if( ((reader).ptr += (((CvSeq*)reader.seq)->elem_size)) >= (reader).block_max )
{
cvChangeSeqBlock( (CvSeqReader*)&(reader), 1 );
}
}
remaining--;
}
return *this;
@ -5368,7 +5373,12 @@ FileNodeIterator& FileNodeIterator::operator --()
if( remaining < FileNode(fs, container).size() )
{
if( reader.seq )
CV_PREV_SEQ_ELEM( reader.seq->elem_size, reader );
{
if( ((reader).ptr -= (((CvSeq*)reader.seq)->elem_size)) < (reader).block_min )
{
cvChangeSeqBlock( (CvSeqReader*)&(reader), -1 );
}
}
remaining++;
}
return *this;
@ -5394,7 +5404,7 @@ FileNodeIterator& FileNodeIterator::operator += (int ofs)
}
remaining -= ofs;
if( reader.seq )
cvSetSeqReaderPos( &reader, ofs, 1 );
cvSetSeqReaderPos( (CvSeqReader*)&reader, ofs, 1 );
return *this;
}
@ -5415,7 +5425,7 @@ FileNodeIterator& FileNodeIterator::readRaw( const String& fmt, uchar* vec, size
if( reader.seq )
{
cvReadRawDataSlice( fs, &reader, (int)count, vec, fmt.c_str() );
cvReadRawDataSlice( fs, (CvSeqReader*)&reader, (int)count, vec, fmt.c_str() );
remaining -= count*cn;
}
else
@ -5475,14 +5485,17 @@ void write( FileStorage& fs, const String& name, const SparseMat& value )
}
WriteStructContext::WriteStructContext(FileStorage& _fs, const String& name,
int flags, const String& typeName) : fs(&_fs)
internal::WriteStructContext::WriteStructContext(FileStorage& _fs,
const String& name, int flags, const String& typeName) : fs(&_fs)
{
cvStartWriteStruct(**fs, !name.empty() ? name.c_str() : 0, flags,
!typeName.empty() ? typeName.c_str() : 0);
}
WriteStructContext::~WriteStructContext() { cvEndWriteStruct(**fs); }
internal::WriteStructContext::~WriteStructContext()
{
cvEndWriteStruct(**fs);
}
void read( const FileNode& node, Mat& mat, const Mat& default_mat )
@ -5524,7 +5537,7 @@ void read( const FileNode& node, SparseMat& mat, const SparseMat& default_mat )
void write(FileStorage& fs, const String& objname, const std::vector<KeyPoint>& keypoints)
{
WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW);
internal::WriteStructContext ws(fs, objname, CV_NODE_SEQ + CV_NODE_FLOW);
int i, npoints = (int)keypoints.size();
for( i = 0; i < npoints; i++ )

@ -13,4 +13,6 @@
#include "opencv2/ts.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/private.hpp"
#endif

@ -619,7 +619,7 @@ void LDetector::read(const FileNode& objnode)
void LDetector::write(FileStorage& fs, const String& name) const
{
WriteStructContext ws(fs, name, CV_NODE_MAP);
internal::WriteStructContext ws(fs, name, CV_NODE_MAP);
fs << "radius" << radius
<< "threshold" << threshold
@ -709,7 +709,7 @@ FernClassifier::FernClassifier(const std::vector<std::vector<Point2f> >& points,
void FernClassifier::write(FileStorage& fs, const String& objname) const
{
WriteStructContext ws(fs, objname, CV_NODE_MAP);
internal::WriteStructContext ws(fs, objname, CV_NODE_MAP);
cv::write(fs, "nstructs", nstructs);
cv::write(fs, "struct-size", structSize);
@ -718,7 +718,7 @@ void FernClassifier::write(FileStorage& fs, const String& objname) const
cv::write(fs, "compression-method", compressionMethod);
cv::write(fs, "patch-size", patchSize.width);
{
WriteStructContext wsf(fs, "features", CV_NODE_SEQ + CV_NODE_FLOW);
internal::WriteStructContext wsf(fs, "features", CV_NODE_SEQ + CV_NODE_FLOW);
int i, nfeatures = (int)features.size();
for( i = 0; i < nfeatures; i++ )
{
@ -727,7 +727,7 @@ void FernClassifier::write(FileStorage& fs, const String& objname) const
}
}
{
WriteStructContext wsp(fs, "posteriors", CV_NODE_SEQ + CV_NODE_FLOW);
internal::WriteStructContext wsp(fs, "posteriors", CV_NODE_SEQ + CV_NODE_FLOW);
cv::write(fs, posteriors);
}
}
@ -1478,10 +1478,10 @@ void PlanarObjectDetector::read(const FileNode& node)
void PlanarObjectDetector::write(FileStorage& fs, const String& objname) const
{
WriteStructContext ws(fs, objname, CV_NODE_MAP);
internal::WriteStructContext ws(fs, objname, CV_NODE_MAP);
{
WriteStructContext wsroi(fs, "model-roi", CV_NODE_SEQ + CV_NODE_FLOW);
internal::WriteStructContext wsroi(fs, "model-roi", CV_NODE_SEQ + CV_NODE_FLOW);
cv::write(fs, modelROI.x);
cv::write(fs, modelROI.y);
cv::write(fs, modelROI.width);

@ -24,7 +24,9 @@ ocv_module_include_directories(
set(opencv_hdrs
"${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core.hpp"
"${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/base.hpp"
"${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/types.hpp"
"${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/persistence.hpp"
"${OPENCV_MODULE_opencv_core_LOCATION}/include/opencv2/core/utility.hpp"
"${OPENCV_MODULE_opencv_flann_LOCATION}/include/opencv2/flann/miniflann.hpp"
"${OPENCV_MODULE_opencv_imgproc_LOCATION}/include/opencv2/imgproc.hpp"

Loading…
Cancel
Save