From 676f19233a6185f92cf323a8c93d1fdb09a572c3 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Tue, 24 Jan 2012 20:14:07 +0000 Subject: [PATCH] added the abstract cv::Algorithm class; low-level exp & fastAtan etc. functions for more efficient SIFT implementation; fixed bug #1521 --- modules/core/include/opencv2/core/core.hpp | 167 ++++-- modules/core/include/opencv2/core/mat.hpp | 20 + .../core/include/opencv2/core/operations.hpp | 81 ++- modules/core/include/opencv2/core/types_c.h | 2 - modules/core/src/algorithm.cpp | 499 ++++++++++++++++++ modules/core/src/mathfuncs.cpp | 21 + 6 files changed, 724 insertions(+), 66 deletions(-) create mode 100644 modules/core/src/algorithm.cpp diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 6e7801f076..6353831836 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -989,7 +989,6 @@ public: typedef value_type work_type; typedef value_type channel_type; typedef value_type vec_type; - enum { generic_type = 1, depth = -1, channels = 1, fmt=0, type = CV_MAKETYPE(depth, channels) }; }; @@ -1209,7 +1208,6 @@ public: type = CV_MAKETYPE(depth, channels) }; typedef Vec vec_type; }; - //////////////////// generic_type ref-counting pointer class for C/C++ objects //////////////////////// @@ -1256,6 +1254,9 @@ public: //! returns true iff obj==NULL bool empty() const; + //! cast pointer to another type + template Ptr<_Tp2> ptr(); + template const Ptr<_Tp2> ptr() const; //! helper operators making "Ptr ptr" use very similar to "T* ptr". _Tp* operator -> (); @@ -1264,7 +1265,6 @@ public: operator _Tp* (); operator const _Tp*() const; -protected: _Tp* obj; //< the object pointer. int* refcount; //< the associated reference counter }; @@ -2154,6 +2154,12 @@ CV_EXPORTS_W void log(InputArray src, OutputArray dst); CV_EXPORTS_W float cubeRoot(float val); //! computes the angle in degrees (0..360) of the vector (x,y) CV_EXPORTS_W float fastAtan2(float y, float x); + +CV_EXPORTS void exp(const float* src, float* dst, int n); +CV_EXPORTS void log(const float* src, float* dst, int n); +CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees); +CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n); + //! converts polar coordinates to Cartesian CV_EXPORTS_W void polarToCart(InputArray magnitude, InputArray angle, OutputArray x, OutputArray y, bool angleInDegrees=false); @@ -4219,54 +4225,145 @@ public: }; -#if 0 -class CV_EXPORTS AlgorithmImpl; - +class CV_EXPORTS Algorithm; +class CV_EXPORTS AlgorithmInfo; +struct CV_EXPORTS AlgorithmInfoData; + +template struct ParamType {}; + /*! Base class for high-level OpenCV algorithms */ class CV_EXPORTS Algorithm { public: + Algorithm(); virtual ~Algorithm(); - virtual string name() const; + string name() const; + + template typename ParamType<_Tp>::member_type get(const string& name) const; + template typename ParamType<_Tp>::member_type get(const char* name) const; + template void set(const string& name, + typename ParamType<_Tp>::const_param_type value); + template void set(const char* name, + typename ParamType<_Tp>::const_param_type value); + string paramHelp(const string& name) const; + int paramType(const char* name) const; + int paramType(const string& name) const; + void getParams(vector& names) const; - template _Tp get(int paramId) const; - template bool set(int paramId, const _Tp& value); - string paramName(int paramId) const; - string paramHelp(int paramId) const; - int paramType(int paramId) const; - int findParam(const string& name) const; - template _Tp paramDefaultValue(int paramId) const; - template bool paramRange(int paramId, _Tp& minVal, _Tp& maxVal) const; - virtual void getParams(vector& ids) const; - virtual void write(vector& buf) const; - virtual bool read(const vector& buf); + virtual void write(FileStorage& fs) const; + virtual void read(const FileNode& fn); typedef Algorithm* (*Constructor)(void); - static void add(const string& name, Constructor create); + typedef int (Algorithm::*Getter)() const; + typedef void (Algorithm::*Setter)(int); + static void getList(vector& algorithms); - static Ptr create(const string& name); + static Ptr _create(const string& name); + template static Ptr<_Tp> create(const string& name); + + virtual AlgorithmInfo* info() const /* TODO: make it = 0;*/ { return 0; } +}; + +class CV_EXPORTS AlgorithmInfo +{ +public: + AlgorithmInfo(const string& name, Algorithm::Constructor create); + ~AlgorithmInfo(); + void get(const Algorithm* algo, const char* name, int argType, void* value) const; + void set(Algorithm* algo, const char* name, int argType, const void* value) const; + void addParam_(const Algorithm* algo, const char* name, int argType, + const void* value, bool readOnly, + Algorithm::Getter getter, Algorithm::Setter setter, + const string& help=string()); + string paramHelp(const char* name) const; + int paramType(const char* name) const; + void getParams(vector& names) const; + + void write(const Algorithm* algo, FileStorage& fs) const; + void read(Algorithm* algo, const FileNode& fn) const; + string name() const; + + template void addParam(const Algorithm* algo, const char* name, + const typename ParamType<_Tp>::member_type& value, + bool readOnly=false, + typename ParamType<_Tp>::member_type (Algorithm::*getter)()=0, + void (Algorithm::*setter)(typename ParamType<_Tp>::const_param_type)=0, + const string& help=string()); protected: - template void addParam(int propId, _Tp& value, bool readOnly, const string& name, - const string& help=string(), const _Tp& defaultValue=_Tp(), - _Tp (Algorithm::*getter)()=0, bool (Algorithm::*setter)(const _Tp&)=0); - template void setParamRange(int propId, const _Tp& minVal, const _Tp& maxVal); - - bool set_(int paramId, int argType, const void* value); - void get_(int paramId, int argType, void* value); - void paramDefaultValue_(int paramId, int argType, void* value); - void paramRange_(int paramId, int argType, void* minval, void* maxval); - void addParam_(int propId, int argType, void* value, bool readOnly, const string& name, - const string& help, const void* defaultValue, void* getter, void* setter); - void setParamRange_(int propId, int argType, const void* minVal, const void* maxVal); - - Ptr impl; + AlgorithmInfoData* data; +}; + + +struct CV_EXPORTS Param +{ + enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, ALGORITHM=5 }; + + Param(); + Param(int _type, bool _readonly, int _offset, + Algorithm::Getter _getter=0, + Algorithm::Setter _setter=0, + const string& _help=string()); + int type; + int offset; + bool readonly; + Algorithm::Getter getter; + Algorithm::Setter setter; + string help; +}; + +template<> struct ParamType +{ + typedef bool const_param_type; + typedef bool member_type; + + enum { type = Param::BOOLEAN }; +}; + +template<> struct ParamType +{ + typedef int const_param_type; + typedef int member_type; + + enum { type = Param::INT }; +}; + +template<> struct ParamType +{ + typedef double const_param_type; + typedef double member_type; + + enum { type = Param::REAL }; +}; + +template<> struct ParamType +{ + typedef const string& const_param_type; + typedef string member_type; + + enum { type = Param::STRING }; +}; + +template<> struct ParamType +{ + typedef const Mat& const_param_type; + typedef Mat member_type; + + enum { type = Param::MAT }; }; -#endif +template<> struct ParamType +{ + typedef const Ptr& const_param_type; + typedef Ptr member_type; + + enum { type = Param::ALGORITHM }; +}; + + /*! "\nThe CommandLineParser class is designed for command line arguments parsing\n" "Keys map: \n" diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 04fc119e72..13ed04ac28 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -613,6 +613,16 @@ template inline const _Tp& Mat::at(const int* idx) const CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); return *(const _Tp*)ptr(idx); } +template _Tp& Mat::at(const Vec& idx) +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(_Tp*)ptr(idx.val); +} +template inline const _Tp& Mat::at(const Vec& idx) const +{ + CV_DbgAssert( elemSize() == CV_ELEM_SIZE(DataType<_Tp>::type) ); + return *(const _Tp*)ptr(idx.val); +} template inline MatConstIterator_<_Tp> Mat::begin() const @@ -1025,6 +1035,16 @@ template inline const _Tp& Mat_<_Tp>::operator ()(const int* idx) return Mat::at<_Tp>(idx); } +template template inline _Tp& Mat_<_Tp>::operator ()(const Vec& idx) +{ + return Mat::at<_Tp>(idx); +} + +template template inline const _Tp& Mat_<_Tp>::operator ()(const Vec& idx) const +{ + return Mat::at<_Tp>(idx); +} + template inline _Tp& Mat_<_Tp>::operator ()(int i0) { return this->at<_Tp>(i0); diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index a8d704e5b7..4e71816027 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -2601,6 +2601,30 @@ template inline Ptr<_Tp>::operator const _Tp*() const { return obj template inline bool Ptr<_Tp>::empty() const { return obj == 0; } +template template inline Ptr<_Tp2> Ptr<_Tp>::ptr() +{ + Ptr<_Tp2> p; + if( !obj ) + return p; + if( refcount ) + CV_XADD(refcount, 1); + p.obj = dynamic_cast<_Tp2*>(obj); + p.refcount = refcount; + return p; +} + +template template inline const Ptr<_Tp2> Ptr<_Tp>::ptr() const +{ + Ptr<_Tp2> p; + if( !obj ) + return p; + if( refcount ) + CV_XADD(refcount, 1); + p.obj = dynamic_cast<_Tp2*>(obj); + p.refcount = refcount; + return p; +} + //// specializied implementations of Ptr::delete_obj() for classic OpenCV types template<> CV_EXPORTS void Ptr::delete_obj(); @@ -3766,50 +3790,49 @@ template static inline std::ostream& operator << (std::ostream& ou return out; } -/*template struct AlgorithmParamType {}; -template<> struct AlgorithmParamType { enum { type = CV_PARAM_TYPE_INT }; }; -template<> struct AlgorithmParamType { enum { type = CV_PARAM_TYPE_REAL }; }; -template<> struct AlgorithmParamType { enum { type = CV_PARAM_TYPE_STRING }; }; -template<> struct AlgorithmParamType { enum { type = CV_PARAM_TYPE_MAT }; }; - -template _Tp Algorithm::get(int paramId) const + +template inline Ptr<_Tp> Algorithm::create(const string& name) { - _Tp value = _Tp(); - get_(paramId, AlgorithmParamType<_Tp>::type, &value); - return value; + return _create(name).ptr<_Tp>(); } -template bool Algorithm::set(int paramId, const _Tp& value) +template inline typename ParamType<_Tp>::member_type Algorithm::get(const string& name) const { - set_(paramId, AlgorithmParamType<_Tp>::type, &value); + typename ParamType<_Tp>::member_type value; + info()->get(this, name.c_str(), ParamType<_Tp>::type, &value); return value; } - -template _Tp Algorithm::paramDefaultValue(int paramId) const + +template inline typename ParamType<_Tp>::member_type Algorithm::get(const char* name) const { - _Tp value = _Tp(); - paramDefaultValue_(paramId, AlgorithmParamType<_Tp>::type, &value); + typename ParamType<_Tp>::member_type value; + info()->get(this, name, ParamType<_Tp>::type, &value); return value; -} +} -template bool Algorithm::paramRange(int paramId, _Tp& minVal, _Tp& maxVal) const +template inline void Algorithm::set(const string& name, + typename ParamType<_Tp>::const_param_type value) { - return paramRange_(paramId, AlgorithmParamType<_Tp>::type, &minVal, &maxVal); + info()->set(this, name.c_str(), ParamType<_Tp>::type, &value); } -template void Algorithm::addParam(int propId, _Tp& value, bool readOnly, const string& name, - const string& help, const _Tp& defaultValue, - _Tp (Algorithm::*getter)(), bool (Algorithm::*setter)(const _Tp&)) +template inline void Algorithm::set(const char* name, + typename ParamType<_Tp>::const_param_type value) { - addParam_(propId, AlgorithmParamType<_Tp>::type, &value, readOnly, name, help, &defaultValue, - (void*)getter, (void*)setter); + info()->set(this, name, ParamType<_Tp>::type, &value); } - -template void Algorithm::setParamRange(int propId, const _Tp& minVal, const _Tp& maxVal) + +template inline void AlgorithmInfo::addParam(const Algorithm* algo, const char* name, + const typename ParamType<_Tp>::member_type& value, + bool readOnly, + typename ParamType<_Tp>::member_type (Algorithm::*getter)(), + void (Algorithm::*setter)(typename ParamType<_Tp>::const_param_type), + const string& help) { - setParamRange_(propId, AlgorithmParamType<_Tp>::type, &minVal, &maxVal); -}*/ - + addParam_(algo, name, ParamType<_Tp>::type, &value, readOnly, + (Algorithm::Getter)getter, (Algorithm::Setter)setter, help); +} + } #endif // __cplusplus diff --git a/modules/core/include/opencv2/core/types_c.h b/modules/core/include/opencv2/core/types_c.h index cf1d1d992b..5e874af8c1 100644 --- a/modules/core/include/opencv2/core/types_c.h +++ b/modules/core/include/opencv2/core/types_c.h @@ -1878,8 +1878,6 @@ typedef struct CvModuleInfo } CvModuleInfo; -enum { CV_PARAM_TYPE_INT=0, CV_PARAM_TYPE_REAL=1, CV_PARAM_TYPE_STRING=2, CV_PARAM_TYPE_MAT=3 }; - #endif /*_CXCORE_TYPES_H_*/ /* End of file. */ diff --git a/modules/core/src/algorithm.cpp b/modules/core/src/algorithm.cpp new file mode 100644 index 0000000000..cb7e4b9f90 --- /dev/null +++ b/modules/core/src/algorithm.cpp @@ -0,0 +1,499 @@ +/*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-2011, Willow Garage Inc., 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*/ + +#include "precomp.hpp" + +namespace cv +{ + +using std::pair; + +template struct sorted_vector +{ + sorted_vector() {} + void clear() { vec.clear(); } + size_t size() const { return vec.size(); } + _ValueTp& operator [](size_t idx) { return vec[idx]; } + const _ValueTp& operator [](size_t idx) const { return vec[idx]; } + + void add(const _KeyTp& k, const _ValueTp& val) + { + pair<_KeyTp, _ValueTp> p(k, val); + vec.push_back(p); + size_t i = vec.size()-1; + for( ; i > 0 && vec[i].first < vec[i-1].first; i-- ) + std::swap(vec[i-1], vec[i]); + CV_Assert( i == 0 || vec[i].first != vec[i-1].first ); + } + + bool find(const _KeyTp& key, _ValueTp& value) const + { + size_t a = 0, b = vec.size(); + while( b > a ) + { + size_t c = (a + b)/2; + if( vec[c].first < key ) + a = c+1; + else + b = c; + } + + if( vec[a].first == key ) + { + value = vec[a].second; + return true; + } + return false; + } + + void get_keys(vector<_KeyTp>& keys) const + { + size_t i = 0, n = vec.size(); + keys.resize(n); + + for( i = 0; i < n; i++ ) + keys[i] = vec[i].first; + } + + vector > vec; +}; + + +template inline const _ValueTp* findstr(const sorted_vector& vec, + const char* key) +{ + if( !key ) + return 0; + + size_t a = 0, b = vec.vec.size(); + while( b > a ) + { + size_t c = (a + b)/2; + if( strcmp(vec.vec[c].first.c_str(), key) < 0 ) + a = c+1; + else + b = c; + } + + if( strcmp(vec.vec[a].first.c_str(), key) == 0 ) + return &vec.vec[a].second; + return 0; +} + + +Param::Param() +{ + type = 0; + offset = 0; + readonly = false; + getter = 0; + setter = 0; +} + + +Param::Param(int _type, bool _readonly, int _offset, + Algorithm::Getter _getter, Algorithm::Setter _setter, + const string& _help) +{ + type = _type; + readonly = _readonly; + offset = _offset; + getter = _getter; + setter = _setter; + help = _help; +} + +struct CV_EXPORTS AlgorithmInfoData +{ + sorted_vector params; + string _name; +}; + + +static sorted_vector alglist; + +void Algorithm::getList(vector& algorithms) +{ + alglist.get_keys(algorithms); +} + +Ptr Algorithm::_create(const string& name) +{ + Algorithm::Constructor c = 0; + if( !alglist.find(name, c) ) + return Ptr(); + return c(); +} + +Algorithm::Algorithm() +{ +} + +Algorithm::~Algorithm() +{ +} + +string Algorithm::name() const +{ + return info()->name(); +} + +string Algorithm::paramHelp(const string& name) const +{ + return info()->paramHelp(name.c_str()); +} + +int Algorithm::paramType(const string& name) const +{ + return info()->paramType(name.c_str()); +} + +int Algorithm::paramType(const char* name) const +{ + return info()->paramType(name); +} + +void Algorithm::getParams(vector& names) const +{ + info()->getParams(names); +} + +void Algorithm::write(FileStorage& fs) const +{ + info()->write(this, fs); +} + +void Algorithm::read(const FileNode& fn) +{ + info()->read(this, fn); +} + + +AlgorithmInfo::AlgorithmInfo(const string& _name, Algorithm::Constructor create) +{ + data = new AlgorithmInfoData; + data->_name = _name; + alglist.add(_name, create); +} + +AlgorithmInfo::~AlgorithmInfo() +{ + delete data; +} + +void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const +{ + size_t i = 0, n = data->params.vec.size(); + cv::write(fs, "name", algo->name()); + for( i = 0; i < n; i++ ) + { + const Param& p = data->params.vec[i].second; + const string& pname = data->params.vec[i].first; + if( p.type == Param::INT ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::BOOLEAN ) + cv::write(fs, pname, (int)algo->get(pname)); + else if( p.type == Param::REAL ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::STRING ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::MAT ) + cv::write(fs, pname, algo->get(pname)); + else if( p.type == Param::ALGORITHM ) + { + WriteStructContext ws(fs, pname, CV_NODE_MAP); + Ptr nestedAlgo = algo->get(pname); + nestedAlgo->write(fs); + } + else + CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported parameter type"); + } +} + +void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const +{ + size_t i = 0, n = data->params.vec.size(); + + for( i = 0; i < n; i++ ) + { + const Param& p = data->params.vec[i].second; + const string& pname = data->params.vec[i].first; + FileNode n = fn[pname]; + if( n.empty() ) + continue; + if( p.type == Param::INT ) + algo->set(pname, (int)n); + else if( p.type == Param::BOOLEAN ) + algo->set(pname, (int)n != 0); + else if( p.type == Param::REAL ) + algo->set(pname, (double)n); + else if( p.type == Param::STRING ) + algo->set(pname, (string)n); + else if( p.type == Param::MAT ) + { + Mat m; + cv::read(fn, m); + algo->set(pname, m); + } + else if( p.type == Param::ALGORITHM ) + { + Ptr nestedAlgo = Algorithm::_create((string)n["name"]); + CV_Assert( !nestedAlgo.empty() ); + nestedAlgo->read(n); + algo->set(pname, nestedAlgo); + } + else + CV_Error( CV_StsUnsupportedFormat, "unknown/unsupported parameter type"); + } +} + +string AlgorithmInfo::name() const +{ + return data->_name; +} + +union GetSetParam +{ + int (Algorithm::*get_int)() const; + bool (Algorithm::*get_bool)() const; + double (Algorithm::*get_double)() const; + string (Algorithm::*get_string)() const; + Mat (Algorithm::*get_mat)() const; + Ptr (Algorithm::*get_algo)() const; + + void (Algorithm::*set_int)(int); + void (Algorithm::*set_bool)(bool); + void (Algorithm::*set_double)(double); + void (Algorithm::*set_string)(const string&); + void (Algorithm::*set_mat)(const Mat&); + void (Algorithm::*set_algo)(const Ptr&); +}; + +void AlgorithmInfo::set(Algorithm* algo, const char* name, int argType, const void* value) const +{ + const Param* p = findstr(data->params, name); + + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "") ); + + if( p->readonly ) + CV_Error_( CV_StsError, ("Parameter '%s' is readonly", name)); + + GetSetParam f; + f.set_int = p->setter; + + if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL ) + { + CV_Assert( p->type == Param::INT || p->type == Param::REAL || p->type == Param::BOOLEAN ); + + if( p->type == Param::INT ) + { + int val = argType == Param::INT ? *(const int*)value : + argType == Param::BOOLEAN ? (int)*(const bool*)value : + saturate_cast(*(const double*)value); + if( p->setter ) + (algo->*f.set_int)(val); + else + *(int*)((uchar*)algo + p->offset) = val; + } + else if( p->type == Param::BOOLEAN ) + { + bool val = argType == Param::INT ? *(const int*)value != 0 : + argType == Param::BOOLEAN ? *(const bool*)value : + *(const double*)value != 0; + if( p->setter ) + (algo->*f.set_bool)(val); + else + *(bool*)((uchar*)algo + p->offset) = val; + } + else + { + double val = argType == Param::INT ? (double)*(const int*)value : + argType == Param::BOOLEAN ? (double)*(const bool*)value : + *(const double*)value; + if( p->setter ) + (algo->*f.set_double)(val); + else + *(double*)((uchar*)algo + p->offset) = val; + } + } + else if( argType == Param::STRING ) + { + CV_Assert( p->type == Param::STRING ); + + const string& val = *(const string*)value; + if( p->setter ) + (algo->*f.set_string)(val); + else + *(string*)((uchar*)algo + p->offset) = val; + } + else if( argType == Param::MAT ) + { + CV_Assert( p->type == Param::MAT ); + + const Mat& val = *(const Mat*)value; + if( p->setter ) + (algo->*f.set_mat)(val); + else + *(Mat*)((uchar*)algo + p->offset) = val; + } + else if( argType == Param::ALGORITHM ) + { + CV_Assert( p->type == Param::ALGORITHM ); + + const Ptr& val = *(const Ptr*)value; + if( p->setter ) + (algo->*f.set_algo)(val); + else + *(Ptr*)((uchar*)algo + p->offset) = val; + } + else + CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type"); +} + +void AlgorithmInfo::get(const Algorithm* algo, const char* name, int argType, void* value) const +{ + const Param* p = findstr(data->params, name); + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "") ); + + GetSetParam f; + f.get_int = p->getter; + + if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL ) + { + if( p->type == Param::INT ) + { + CV_Assert( argType == Param::INT || argType == Param::REAL ); + int val = p->getter ? (algo->*f.get_int)() : *(int*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = val; + else + *(double*)value = val; + } + else if( p->type == Param::BOOLEAN ) + { + CV_Assert( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL ); + bool val = p->getter ? (algo->*f.get_bool)() : *(bool*)((uchar*)algo + p->offset); + + if( argType == Param::INT ) + *(int*)value = (int)val; + else if( argType == Param::BOOLEAN ) + *(bool*)value = val; + else + *(double*)value = (int)val; + } + else + { + CV_Assert( argType == Param::REAL ); + double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset); + + *(double*)value = val; + } + } + else if( argType == Param::STRING ) + { + CV_Assert( p->type == Param::STRING ); + + *(string*)value = p->getter ? (algo->*f.get_string)() : + *(string*)((uchar*)algo + p->offset); + } + else if( argType == Param::MAT ) + { + CV_Assert( p->type == Param::MAT ); + + *(Mat*)value = p->getter ? (algo->*f.get_mat)() : + *(Mat*)((uchar*)algo + p->offset); + } + else if( argType == Param::ALGORITHM ) + { + CV_Assert( p->type == Param::ALGORITHM ); + + *(Ptr*)value = p->getter ? (algo->*f.get_algo)() : + *(Ptr*)((uchar*)algo + p->offset); + } + else + CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type"); +} + + +int AlgorithmInfo::paramType(const char* name) const +{ + const Param* p = findstr(data->params, name); + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "") ); + return p->type; +} + + +string AlgorithmInfo::paramHelp(const char* name) const +{ + const Param* p = findstr(data->params, name); + if( !p ) + CV_Error_( CV_StsBadArg, ("No parameter '%s' is found", name ? name : "") ); + return p->help; +} + + +void AlgorithmInfo::getParams(vector& names) const +{ + data->params.get_keys(names); +} + + +void AlgorithmInfo::addParam_(const Algorithm* algo, const char* name, int argType, + const void* value, bool readOnly, + Algorithm::Getter getter, Algorithm::Setter setter, + const string& help) +{ + CV_Assert( argType == Param::INT || argType == Param::BOOLEAN || + argType == Param::REAL || argType == Param::STRING || + argType == Param::MAT || argType == Param::ALGORITHM ); + data->params.add(string(name), Param(argType, readOnly, + (int)((size_t)value - (size_t)(void*)algo), + getter, setter, help)); +} + +} + +/* End of file. */ diff --git a/modules/core/src/mathfuncs.cpp b/modules/core/src/mathfuncs.cpp index 1d0100d1e3..3f8308d8e8 100644 --- a/modules/core/src/mathfuncs.cpp +++ b/modules/core/src/mathfuncs.cpp @@ -2113,6 +2113,27 @@ bool checkRange(InputArray _src, bool quiet, Point* pt, return badPt.x < 0; } + +void exp(const float* src, float* dst, int n) +{ + Exp_32f(src, dst, n); +} + +void log(const float* src, float* dst, int n) +{ + Log_32f(src, dst, n); +} + +void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees) +{ + FastAtan2_32f(y, x, dst, n, angleInDegrees); +} + +void magnitude(const float* x, const float* y, float* dst, int n) +{ + Magnitude_32f(x, y, dst, n); +} + } CV_IMPL float cvCbrt(float value) { return cv::cubeRoot(value); }