|
|
|
@ -50,24 +50,29 @@ namespace cv |
|
|
|
|
{ |
|
|
|
|
namespace dnn |
|
|
|
|
{ |
|
|
|
|
//! @addtogroup dnn
|
|
|
|
|
//! @{
|
|
|
|
|
|
|
|
|
|
/** @brief This struct stores the scalar value (or array) of one of the following type: double, cv::String or int64.
|
|
|
|
|
* @todo Maybe int64 is useless because double type exactly stores at least 2^52 integers. |
|
|
|
|
*/ |
|
|
|
|
struct DictValue |
|
|
|
|
{ |
|
|
|
|
DictValue(const DictValue &r); |
|
|
|
|
DictValue(int p = 0) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = p; } |
|
|
|
|
DictValue(unsigned p) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = p; } |
|
|
|
|
DictValue(double p) : type(Param::REAL), pd(new AutoBuffer<double,1>) { (*pd)[0] = p; } |
|
|
|
|
DictValue(const String &p) : type(Param::STRING), ps(new AutoBuffer<String,1>) { (*ps)[0] = p; } |
|
|
|
|
DictValue(int p = 0) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = p; } //!< Constructs integer scalar
|
|
|
|
|
DictValue(unsigned p) : type(Param::INT), pi(new AutoBuffer<int64,1>) { (*pi)[0] = p; } //!< Constructs integer scalar
|
|
|
|
|
DictValue(double p) : type(Param::REAL), pd(new AutoBuffer<double,1>) { (*pd)[0] = p; } //!< Constructs floating point scalar
|
|
|
|
|
DictValue(const String &p) : type(Param::STRING), ps(new AutoBuffer<String,1>) { (*ps)[0] = p; } //!< Constructs string scalar
|
|
|
|
|
|
|
|
|
|
template<typename TypeIter> |
|
|
|
|
static DictValue arrayInt(TypeIter begin, int size); |
|
|
|
|
static DictValue arrayInt(TypeIter begin, int size); //!< Constructs integer array
|
|
|
|
|
template<typename TypeIter> |
|
|
|
|
static DictValue arrayReal(TypeIter begin, int size); |
|
|
|
|
static DictValue arrayReal(TypeIter begin, int size); //!< Constructs floating point array
|
|
|
|
|
template<typename TypeIter> |
|
|
|
|
static DictValue arrayString(TypeIter begin, int size); |
|
|
|
|
static DictValue arrayString(TypeIter begin, int size); //!< Constructs array of strings
|
|
|
|
|
|
|
|
|
|
template<typename T> |
|
|
|
|
T get(int idx = -1) const; |
|
|
|
|
T get(int idx = -1) const; //!< Tries to convert array element with specified index to requested type and returns it.
|
|
|
|
|
|
|
|
|
|
int size() const; |
|
|
|
|
|
|
|
|
@ -81,7 +86,7 @@ struct DictValue |
|
|
|
|
|
|
|
|
|
~DictValue(); |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
private: |
|
|
|
|
|
|
|
|
|
int type; |
|
|
|
|
|
|
|
|
@ -97,33 +102,7 @@ protected: |
|
|
|
|
void release(); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template<typename TypeIter> |
|
|
|
|
DictValue DictValue::arrayInt(TypeIter begin, int size) |
|
|
|
|
{ |
|
|
|
|
DictValue res(Param::INT, new AutoBuffer<int64, 1>(size)); |
|
|
|
|
for (int j = 0; j < size; begin++, j++) |
|
|
|
|
(*res.pi)[j] = *begin; |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<typename TypeIter> |
|
|
|
|
DictValue DictValue::arrayReal(TypeIter begin, int size) |
|
|
|
|
{ |
|
|
|
|
DictValue res(Param::REAL, new AutoBuffer<double, 1>(size)); |
|
|
|
|
for (int j = 0; j < size; begin++, j++) |
|
|
|
|
(*res.pd)[j] = *begin; |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<typename TypeIter> |
|
|
|
|
DictValue DictValue::arrayString(TypeIter begin, int size) |
|
|
|
|
{ |
|
|
|
|
DictValue res(Param::STRING, new AutoBuffer<String, 1>(size)); |
|
|
|
|
for (int j = 0; j < size; begin++, j++) |
|
|
|
|
(*res.ps)[j] = *begin; |
|
|
|
|
return res; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** @brief This class implements name-value dictionary, values are instances of DictValue. */ |
|
|
|
|
class CV_EXPORTS Dict |
|
|
|
|
{ |
|
|
|
|
typedef std::map<String, DictValue> _Dict; |
|
|
|
@ -131,276 +110,31 @@ class CV_EXPORTS Dict |
|
|
|
|
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
bool has(const String &name) |
|
|
|
|
{ |
|
|
|
|
return dict.count(name) != 0; |
|
|
|
|
} |
|
|
|
|
//! Checks a presence of the @p key in the dictionary.
|
|
|
|
|
bool has(const String &key); |
|
|
|
|
|
|
|
|
|
DictValue *ptr(const String &name) |
|
|
|
|
{ |
|
|
|
|
_Dict::iterator i = dict.find(name); |
|
|
|
|
return (i == dict.end()) ? NULL : &i->second; |
|
|
|
|
} |
|
|
|
|
//! If the @p key in the dictionary then returns pointer to its value, else returns NULL.
|
|
|
|
|
DictValue *ptr(const String &key); |
|
|
|
|
|
|
|
|
|
const DictValue &get(const String &name) const |
|
|
|
|
{ |
|
|
|
|
_Dict::const_iterator i = dict.find(name); |
|
|
|
|
if (i == dict.end()) |
|
|
|
|
CV_Error(Error::StsBadArg, "Required argument \"" + name + "\" not found into dictionary"); |
|
|
|
|
return i->second; |
|
|
|
|
} |
|
|
|
|
//! If the @p key in the dictionary then returns its value, else an error will be generated.
|
|
|
|
|
const DictValue &get(const String &key) const; |
|
|
|
|
|
|
|
|
|
/** @overload */ |
|
|
|
|
template <typename T> |
|
|
|
|
T get(const String &name) const |
|
|
|
|
{ |
|
|
|
|
return this->get(name).get<T>(); |
|
|
|
|
} |
|
|
|
|
T get(const String &key) const; |
|
|
|
|
|
|
|
|
|
//! If the @p key in the dictionary then returns its value, else returns @p defaultValue.
|
|
|
|
|
template <typename T> |
|
|
|
|
T get(const String &name, const T &default_value) const |
|
|
|
|
{ |
|
|
|
|
_Dict::const_iterator i = dict.find(name); |
|
|
|
|
|
|
|
|
|
if (i != dict.end()) |
|
|
|
|
return i->second.get<T>(); |
|
|
|
|
else |
|
|
|
|
return default_value; |
|
|
|
|
} |
|
|
|
|
T get(const String &key, const T &defaultValue) const; |
|
|
|
|
|
|
|
|
|
//! Sets new @p value for the @p key, or adds new key-value pair into the dictionary.
|
|
|
|
|
template<typename T> |
|
|
|
|
const T &set(const String &name, const T &value) |
|
|
|
|
{ |
|
|
|
|
_Dict::iterator i = dict.find(name); |
|
|
|
|
|
|
|
|
|
if (i != dict.end()) |
|
|
|
|
i->second = DictValue(value); |
|
|
|
|
else |
|
|
|
|
dict.insert(std::make_pair(name, DictValue(value))); |
|
|
|
|
|
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
const T &set(const String &key, const T &value); |
|
|
|
|
|
|
|
|
|
friend std::ostream &operator<<(std::ostream &stream, const Dict &dict); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline DictValue DictValue::get<DictValue>(int idx) const |
|
|
|
|
{ |
|
|
|
|
CV_Assert(idx == -1); |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline int64 DictValue::get<int64>(int idx) const |
|
|
|
|
{ |
|
|
|
|
CV_Assert(idx == -1 && size() == 1 || idx >= 0 && idx < size()); |
|
|
|
|
idx = (idx == -1) ? 0 : idx; |
|
|
|
|
|
|
|
|
|
if (type == Param::INT) |
|
|
|
|
{ |
|
|
|
|
return (*pi)[idx]; |
|
|
|
|
} |
|
|
|
|
else if (type == Param::REAL) |
|
|
|
|
{ |
|
|
|
|
double doubleValue = (*pd)[idx]; |
|
|
|
|
|
|
|
|
|
double fracpart, intpart; |
|
|
|
|
fracpart = std::modf(doubleValue, &intpart); |
|
|
|
|
CV_Assert(fracpart == 0.0); |
|
|
|
|
|
|
|
|
|
return (int64)doubleValue; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
CV_Assert(isInt() || isReal()); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline int DictValue::get<int>(int idx) const |
|
|
|
|
{ |
|
|
|
|
return (int)get<int64>(idx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline unsigned DictValue::get<unsigned>(int idx) const |
|
|
|
|
{ |
|
|
|
|
return (unsigned)get<int64>(idx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline bool DictValue::get<bool>(int idx) const |
|
|
|
|
{ |
|
|
|
|
return (get<int64>(idx) != 0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline double DictValue::get<double>(int idx) const |
|
|
|
|
{ |
|
|
|
|
CV_Assert(idx == -1 && size() == 1 || idx >= 0 && idx < size()); |
|
|
|
|
idx = (idx == -1) ? 0 : idx; |
|
|
|
|
|
|
|
|
|
if (type == Param::REAL) |
|
|
|
|
{ |
|
|
|
|
return (*pd)[idx]; |
|
|
|
|
} |
|
|
|
|
else if (type == Param::INT) |
|
|
|
|
{ |
|
|
|
|
return (double)(*pi)[idx]; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
CV_Assert(isReal() || isInt()); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline float DictValue::get<float>(int idx) const |
|
|
|
|
{ |
|
|
|
|
return (float)get<double>(idx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
template<> |
|
|
|
|
inline String DictValue::get<String>(int idx) const |
|
|
|
|
{ |
|
|
|
|
CV_Assert(isString()); |
|
|
|
|
CV_Assert(idx == -1 && ps->size() == 1 || idx >= 0 && idx < (int)ps->size()); |
|
|
|
|
return (*ps)[(idx == -1) ? 0 : idx]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline void DictValue::release() |
|
|
|
|
{ |
|
|
|
|
switch (type) |
|
|
|
|
{ |
|
|
|
|
case Param::INT: |
|
|
|
|
delete pi; |
|
|
|
|
break; |
|
|
|
|
case Param::STRING: |
|
|
|
|
delete ps; |
|
|
|
|
break; |
|
|
|
|
case Param::REAL: |
|
|
|
|
delete pd; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline DictValue::~DictValue() |
|
|
|
|
{ |
|
|
|
|
release(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline DictValue & DictValue::operator=(const DictValue &r) |
|
|
|
|
{ |
|
|
|
|
if (&r == this) |
|
|
|
|
return *this; |
|
|
|
|
|
|
|
|
|
if (r.type == Param::INT) |
|
|
|
|
{ |
|
|
|
|
AutoBuffer<int64, 1> *tmp = new AutoBuffer<int64, 1>(*r.pi); |
|
|
|
|
release(); |
|
|
|
|
pi = tmp; |
|
|
|
|
} |
|
|
|
|
else if (r.type == Param::STRING) |
|
|
|
|
{ |
|
|
|
|
AutoBuffer<String, 1> *tmp = new AutoBuffer<String, 1>(*r.ps); |
|
|
|
|
release(); |
|
|
|
|
ps = tmp; |
|
|
|
|
} |
|
|
|
|
else if (r.type == Param::REAL) |
|
|
|
|
{ |
|
|
|
|
AutoBuffer<double, 1> *tmp = new AutoBuffer<double, 1>(*r.pd); |
|
|
|
|
release(); |
|
|
|
|
pd = tmp; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type = r.type; |
|
|
|
|
|
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline DictValue::DictValue(const DictValue &r) |
|
|
|
|
{ |
|
|
|
|
type = r.type; |
|
|
|
|
|
|
|
|
|
if (r.type == Param::INT) |
|
|
|
|
pi = new AutoBuffer<int64, 1>(*r.pi); |
|
|
|
|
else if (r.type == Param::STRING) |
|
|
|
|
ps = new AutoBuffer<String, 1>(*r.ps); |
|
|
|
|
else if (r.type == Param::REAL) |
|
|
|
|
pd = new AutoBuffer<double, 1>(*r.pd); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool DictValue::isString() const |
|
|
|
|
{ |
|
|
|
|
return (type == Param::STRING); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool DictValue::isInt() const |
|
|
|
|
{ |
|
|
|
|
return (type == Param::INT); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline bool DictValue::isReal() const |
|
|
|
|
{ |
|
|
|
|
return (type == Param::REAL || type == Param::INT); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline int DictValue::size() const |
|
|
|
|
{ |
|
|
|
|
switch (type) |
|
|
|
|
{ |
|
|
|
|
case Param::INT: |
|
|
|
|
return (int)pi->size(); |
|
|
|
|
break; |
|
|
|
|
case Param::STRING: |
|
|
|
|
return (int)ps->size(); |
|
|
|
|
break; |
|
|
|
|
case Param::REAL: |
|
|
|
|
return (int)pd->size(); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
CV_Error(Error::StsInternal, ""); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline std::ostream &operator<<(std::ostream &stream, const DictValue &dictv) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
if (dictv.isInt()) |
|
|
|
|
{ |
|
|
|
|
for (i = 0; i < dictv.size() - 1; i++) |
|
|
|
|
stream << dictv.get<int64>(i) << ", "; |
|
|
|
|
stream << dictv.get<int64>(i); |
|
|
|
|
} |
|
|
|
|
else if (dictv.isReal()) |
|
|
|
|
{ |
|
|
|
|
for (i = 0; i < dictv.size() - 1; i++) |
|
|
|
|
stream << dictv.get<double>(i) << ", "; |
|
|
|
|
stream << dictv.get<double>(i); |
|
|
|
|
} |
|
|
|
|
else if (dictv.isString()) |
|
|
|
|
{ |
|
|
|
|
for (i = 0; i < dictv.size() - 1; i++) |
|
|
|
|
stream << "\"" << dictv.get<String>(i) << "\", "; |
|
|
|
|
stream << dictv.get<String>(i); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return stream; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline std::ostream &operator<<(std::ostream &stream, const Dict &dict) |
|
|
|
|
{ |
|
|
|
|
Dict::_Dict::const_iterator it; |
|
|
|
|
for (it = dict.dict.begin(); it != dict.dict.end(); it++) |
|
|
|
|
stream << it->first << " : " << it->second << "\n"; |
|
|
|
|
|
|
|
|
|
return stream; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//! @}
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|