Added float, uint64, and uchar params to Algorithm
authorLeonidBeynenson <leonid.beynenson@itseez.com>
Mon, 4 Feb 2013 16:25:18 +0000 (20:25 +0400)
committerLeonidBeynenson <leonid.beynenson@itseez.com>
Mon, 4 Feb 2013 16:25:18 +0000 (20:25 +0400)
Made changes to work in cv::Algorithm with parameters of these types.
Also fixed SimpleBlobDetector -- now it can be created by
cv::Algorithm::create and it can work with cv::Algorithm::set/get.

modules/core/include/opencv2/core/core.hpp
modules/core/src/algorithm.cpp
modules/features2d/include/opencv2/features2d/features2d.hpp
modules/features2d/src/features2d_init.cpp

index 9d25916..3bcef2a 100644 (file)
@@ -4340,6 +4340,8 @@ public:
     CV_WRAP Mat getMat(const string& name) const;
     CV_WRAP vector<Mat> getMatVector(const string& name) const;
     CV_WRAP Ptr<Algorithm> getAlgorithm(const string& name) const;
+    CV_WRAP float getFloat(const string& name) const;
+    CV_WRAP uint64 getUInt64(const string& name) const;
 
     void set(const string& name, int value);
     void set(const string& name, double value);
@@ -4376,6 +4378,8 @@ public:
     void setMatVector(const char* name, const vector<Mat>& value);
     void setAlgorithm(const char* name, const Ptr<Algorithm>& value);
     template<typename _Tp> void setAlgorithm(const char* name, const Ptr<_Tp>& value);
+    void setFloat(const char* name, float value);
+    void setUInt64(const char* name, uint64 value);
 
     CV_WRAP string paramHelp(const string& name) const;
     int paramType(const char* name) const;
@@ -4457,6 +4461,26 @@ public:
                   Ptr<Algorithm> (Algorithm::*getter)()=0,
                   void (Algorithm::*setter)(const Ptr<Algorithm>&)=0,
                   const string& help=string());
+    void addParam(Algorithm& algo, const char* name,
+                  float& value, bool readOnly=false,
+                  float (Algorithm::*getter)()=0,
+                  void (Algorithm::*setter)(float)=0,
+                  const string& help=string());
+    void addParam(Algorithm& algo, const char* name,
+                  unsigned int& value, bool readOnly=false,
+                  unsigned int (Algorithm::*getter)()=0,
+                  void (Algorithm::*setter)(unsigned int)=0,
+                  const string& help=string());
+    void addParam(Algorithm& algo, const char* name,
+                  uint64& value, bool readOnly=false,
+                  uint64 (Algorithm::*getter)()=0,
+                  void (Algorithm::*setter)(uint64)=0,
+                  const string& help=string());
+    void addParam(Algorithm& algo, const char* name,
+                  uchar& value, bool readOnly=false,
+                  uchar (Algorithm::*getter)()=0,
+                  void (Algorithm::*setter)(uchar)=0,
+                  const string& help=string());
     template<typename _Tp, typename _Base> void addParam(Algorithm& algo, const char* name,
                   Ptr<_Tp>& value, bool readOnly=false,
                   Ptr<_Tp> (Algorithm::*getter)()=0,
@@ -4476,7 +4500,7 @@ protected:
 
 struct CV_EXPORTS Param
 {
-    enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9, SHORT=10 };
+    enum { INT=0, BOOLEAN=1, REAL=2, STRING=3, MAT=4, MAT_VECTOR=5, ALGORITHM=6, FLOAT=7, UNSIGNED_INT=8, UINT64=9, SHORT=10, UCHAR=11 };
 
     Param();
     Param(int _type, bool _readonly, int _offset,
@@ -4579,6 +4603,13 @@ template<> struct ParamType<uint64>
     enum { type = Param::UINT64 };
 };
 
+template<> struct ParamType<uchar>
+{
+    typedef uchar const_param_type;
+    typedef uchar member_type;
+
+    enum { type = Param::UCHAR };
+};
 
 /*!
 "\nThe CommandLineParser class is designed for command line arguments parsing\n"
index 9c46d1c..c502457 100644 (file)
@@ -322,6 +322,17 @@ void Algorithm::setAlgorithm(const char* parameter, const Ptr<Algorithm>& value)
     info()->set(this, parameter, ParamType<Algorithm>::type, &value);
 }
 
+void Algorithm::setFloat(const char* parameter, float value)
+{
+    info()->set(this, parameter, ParamType<float>::type, &value);
+}
+
+void Algorithm::setUInt64(const char* parameter, uint64 value)
+{
+    info()->set(this, parameter, ParamType<uint64>::type, &value);
+}
+
+
 
 
 int Algorithm::getInt(const string& parameter) const
@@ -359,6 +370,15 @@ Ptr<Algorithm> Algorithm::getAlgorithm(const string& parameter) const
     return get<Algorithm>(parameter);
 }
 
+float Algorithm::getFloat(const string& parameter) const
+{
+    return get<float>(parameter);
+}
+uint64 Algorithm::getUInt64(const string& parameter) const
+{
+    return get<uint64>(parameter);
+}
+
 string Algorithm::paramHelp(const string& parameter) const
 {
     return info()->paramHelp(parameter.c_str());
@@ -431,6 +451,14 @@ void AlgorithmInfo::write(const Algorithm* algo, FileStorage& fs) const
             Ptr<Algorithm> nestedAlgo = algo->get<Algorithm>(pname);
             nestedAlgo->write(fs);
         }
+        else if( p.type == Param::FLOAT)
+            cv::write(fs, pname, algo->getFloat(pname));
+        else if( p.type == Param::UNSIGNED_INT)
+            cv::write(fs, pname, algo->getInt(pname));//TODO: implement cv::write(, , unsigned int)
+        else if( p.type == Param::UINT64)
+            cv::write(fs, pname, algo->getInt(pname));//TODO: implement cv::write(, , uint64)
+        else if( p.type == Param::UCHAR)
+            cv::write(fs, pname, algo->getInt(pname));
         else
         {
             string msg = format("unknown/unsupported type of '%s' parameter == %d", pname.c_str(), p.type);
@@ -490,6 +518,26 @@ void AlgorithmInfo::read(Algorithm* algo, const FileNode& fn) const
             nestedAlgo->read(n);
             info->set(algo, pname.c_str(), p.type, &nestedAlgo, true);
         }
+        else if( p.type == Param::FLOAT )
+        {
+            float val = (float)n;
+            info->set(algo, pname.c_str(), p.type, &val, true);
+        }
+        else if( p.type == Param::UNSIGNED_INT )
+        {
+            unsigned int val = (unsigned int)((int)n);//TODO: implement conversion (unsigned int)FileNode
+            info->set(algo, pname.c_str(), p.type, &val, true);
+        }
+        else if( p.type == Param::UINT64)
+        {
+            uint64 val = (uint64)((int)n);//TODO: implement conversion (uint64)FileNode
+            info->set(algo, pname.c_str(), p.type, &val, true);
+        }
+        else if( p.type == Param::UCHAR)
+        {
+            uchar val = (uchar)((int)n);
+            info->set(algo, pname.c_str(), p.type, &val, true);
+        }
         else
         {
             string msg = format("unknown/unsupported type of '%s' parameter == %d", pname.c_str(), p.type);
@@ -512,6 +560,10 @@ union GetSetParam
     Mat (Algorithm::*get_mat)() const;
     vector<Mat> (Algorithm::*get_mat_vector)() const;
     Ptr<Algorithm> (Algorithm::*get_algo)() const;
+    float (Algorithm::*get_float)() const;
+    unsigned int (Algorithm::*get_uint)() const;
+    uint64 (Algorithm::*get_uint64)() const;
+    uchar (Algorithm::*get_uchar)() const;
 
     void (Algorithm::*set_int)(int);
     void (Algorithm::*set_bool)(bool);
@@ -520,6 +572,10 @@ union GetSetParam
     void (Algorithm::*set_mat)(const Mat&);
     void (Algorithm::*set_mat_vector)(const vector<Mat>&);
     void (Algorithm::*set_algo)(const Ptr<Algorithm>&);
+    void (Algorithm::*set_float)(float);
+    void (Algorithm::*set_uint)(unsigned int);
+    void (Algorithm::*set_uint64)(uint64);
+    void (Algorithm::*set_uchar)(uchar);
 };
 
 static string getNameOfType(int argType);
@@ -536,6 +592,10 @@ static string getNameOfType(int argType)
         case Param::MAT: return "cv::Mat";
         case Param::MAT_VECTOR: return "std::vector<cv::Mat>";
         case Param::ALGORITHM: return "algorithm";
+        case Param::FLOAT: return "float";
+        case Param::UNSIGNED_INT: return "unsigned int";
+        case Param::UINT64: return "unsigned int64";
+        case Param::UCHAR: return "unsigned char";
         default: CV_Error(CV_StsBadArg, "Wrong argument type");
     }
     return "";
@@ -547,9 +607,10 @@ static string getErrorMessageForWrongArgumentInSetter(string algoName, string pa
         + " method was called for the parameter '" + paramName + "' of the algorithm '" + algoName
         +"', the parameter has " + getNameOfType(paramType) + " type, ";
 
-    if (paramType == Param::INT || paramType == Param::BOOLEAN || paramType == Param::REAL)
+    if (paramType == Param::INT || paramType == Param::BOOLEAN || paramType == Param::REAL
+            || paramType == Param::FLOAT || paramType == Param::UNSIGNED_INT || paramType == Param::UINT64 || paramType == Param::UCHAR)
     {
-        message += "so it should be set by integer, boolean, or double value, ";
+        message += "so it should be set by integer, unsigned integer, uint64, unsigned char, boolean, float or double value, ";
     }
     else if (paramType == Param::SHORT)
     {
@@ -569,16 +630,20 @@ static string getErrorMessageForWrongArgumentInGetter(string algoName, string pa
 
     if (paramType == Param::BOOLEAN)
     {
-        message += "so it should be get as integer, boolean, or double value, ";
+        message += "so it should be get as integer, unsigned integer, uint64, boolean, float or double value, ";
     }
-    else if (paramType == Param::INT)
+    else if (paramType == Param::INT || paramType == Param::UNSIGNED_INT || paramType == Param::UINT64 || paramType == Param::UCHAR)
     {
-        message += "so it should be get as integer or double value, ";
+        message += "so it should be get as integer, unsigned integer, uint64, unsigned char, float or double value, ";
     }
     else if (paramType == Param::SHORT)
     {
         message += "so it should be get as integer value, ";
     }
+    else if (paramType == Param::FLOAT || paramType == Param::REAL)
+    {
+        message += "so it should be get as float or double value, ";
+    }
     message += "but the getter was called to get a " + getNameOfType(argType) + " value";
 
     return message;
@@ -597,9 +662,12 @@ void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, con
     GetSetParam f;
     f.set_int = p->setter;
 
-    if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT )
+    if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT
+            || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)
     {
-        if ( !( p->type == Param::INT || p->type == Param::REAL || p->type == Param::BOOLEAN || (p->type == Param::SHORT && argType == Param::INT)) )
+        if ( !( p->type == Param::INT || p->type == Param::REAL || p->type == Param::BOOLEAN
+                || p->type == Param::UNSIGNED_INT || p->type == Param::UINT64 || p->type == Param::FLOAT || argType == Param::UCHAR
+                || (p->type == Param::SHORT && argType == Param::INT)) )
         {
             string message = getErrorMessageForWrongArgumentInSetter(algo->name(), parameter, p->type, argType);
             CV_Error(CV_StsBadArg, message);
@@ -607,9 +675,21 @@ void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, con
 
         if( p->type == Param::INT )
         {
+            bool is_ok = true;
             int val = argType == Param::INT ? *(const int*)value :
-            argType == Param::BOOLEAN ? (int)*(const bool*)value :
-            saturate_cast<int>(*(const double*)value);
+                argType == Param::BOOLEAN ? (int)*(const bool*)value :
+                argType == Param::REAL ? saturate_cast<int>(*(const double*)value) :
+                argType == Param::FLOAT ?  saturate_cast<int>(*(const float*)value) :
+                argType == Param::UNSIGNED_INT ? (int)*(const unsigned int*)value :
+                argType == Param::UINT64 ? (int)*(const uint64*)value :
+                argType == Param::UCHAR ? (int)*(const uchar*)value :
+                (int)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
+
             if( p->setter )
                 (algo->*f.set_int)(val);
             else
@@ -617,6 +697,7 @@ void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, con
         }
         else if( p->type == Param::SHORT )
         {
+            CV_DbgAssert(argType == Param::INT);
             int val = *(const int*)value;
             if( p->setter )
                 (algo->*f.set_int)(val);
@@ -625,24 +706,133 @@ void AlgorithmInfo::set(Algorithm* algo, const char* parameter, int argType, con
         }
         else if( p->type == Param::BOOLEAN )
         {
+            bool is_ok = true;
             bool val = argType == Param::INT ? *(const int*)value != 0 :
                     argType == Param::BOOLEAN ? *(const bool*)value :
-                    *(const double*)value != 0;
+                    argType == Param::REAL ? (*(const double*)value != 0) :
+                    argType == Param::FLOAT ?  (*(const float*)value != 0) :
+                    argType == Param::UNSIGNED_INT ? (*(const unsigned int*)value != 0):
+                    argType == Param::UINT64 ? (*(const uint64*)value != 0):
+                    argType == Param::UCHAR ? (*(const uchar*)value != 0):
+                    (int)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
+
             if( p->setter )
                 (algo->*f.set_bool)(val);
             else
                 *(bool*)((uchar*)algo + p->offset) = val;
         }
-        else
+        else if( p->type == Param::REAL )
         {
+            bool is_ok = true;
             double val = argType == Param::INT ? (double)*(const int*)value :
                          argType == Param::BOOLEAN ? (double)*(const bool*)value :
-                        *(const double*)value;
+                         argType == Param::REAL ? (double)(*(const double*)value ) :
+                         argType == Param::FLOAT ?  (double)(*(const float*)value ) :
+                         argType == Param::UNSIGNED_INT ? (double)(*(const unsigned int*)value ) :
+                         argType == Param::UINT64 ? (double)(*(const uint64*)value ) :
+                         argType == Param::UCHAR ? (double)(*(const uchar*)value ) :
+                         (double)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
             if( p->setter )
                 (algo->*f.set_double)(val);
             else
                 *(double*)((uchar*)algo + p->offset) = val;
         }
+        else if( p->type == Param::FLOAT )
+        {
+            bool is_ok = true;
+            double val = argType == Param::INT ? (double)*(const int*)value :
+                         argType == Param::BOOLEAN ? (double)*(const bool*)value :
+                         argType == Param::REAL ? (double)(*(const double*)value ) :
+                         argType == Param::FLOAT ?  (double)(*(const float*)value ) :
+                         argType == Param::UNSIGNED_INT ? (double)(*(const unsigned int*)value ) :
+                         argType == Param::UINT64 ? (double)(*(const uint64*)value ) :
+                         argType == Param::UCHAR ? (double)(*(const uchar*)value ) :
+                         (double)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
+            if( p->setter )
+                (algo->*f.set_float)((float)val);
+            else
+                *(float*)((uchar*)algo + p->offset) = (float)val;
+        }
+        else if( p->type == Param::UNSIGNED_INT )
+        {
+            bool is_ok = true;
+            unsigned int val = argType == Param::INT ? (unsigned int)*(const int*)value :
+                         argType == Param::BOOLEAN ? (unsigned int)*(const bool*)value :
+                         argType == Param::REAL ? saturate_cast<unsigned int>(*(const double*)value ) :
+                         argType == Param::FLOAT ?  saturate_cast<unsigned int>(*(const float*)value ) :
+                         argType == Param::UNSIGNED_INT ? (unsigned int)(*(const unsigned int*)value ) :
+                         argType == Param::UINT64 ? (unsigned int)(*(const uint64*)value ) :
+                         argType == Param::UCHAR ? (unsigned int)(*(const uchar*)value ) :
+                         (int)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
+            if( p->setter )
+                (algo->*f.set_uint)(val);
+            else
+                *(unsigned int*)((uchar*)algo + p->offset) = val;
+        }
+        else if( p->type == Param::UINT64 )
+        {
+            bool is_ok = true;
+            uint64 val = argType == Param::INT ? (uint64)*(const int*)value :
+                         argType == Param::BOOLEAN ? (uint64)*(const bool*)value :
+                         argType == Param::REAL ? saturate_cast<uint64>(*(const double*)value ) :
+                         argType == Param::FLOAT ?  saturate_cast<uint64>(*(const float*)value ) :
+                         argType == Param::UNSIGNED_INT ? (uint64)(*(const unsigned int*)value ) :
+                         argType == Param::UINT64 ? (uint64)(*(const uint64*)value ) :
+                         argType == Param::UCHAR ? (uint64)(*(const uchar*)value ) :
+                         (int)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
+            if( p->setter )
+                (algo->*f.set_uint64)(val);
+            else
+                *(uint64*)((uchar*)algo + p->offset) = val;
+        }
+        else if( p->type == Param::UCHAR )
+        {
+            bool is_ok = true;
+            uchar val = argType == Param::INT ? (uchar)*(const int*)value :
+                         argType == Param::BOOLEAN ? (uchar)*(const bool*)value :
+                         argType == Param::REAL ? saturate_cast<uchar>(*(const double*)value ) :
+                         argType == Param::FLOAT ?  saturate_cast<uchar>(*(const float*)value ) :
+                         argType == Param::UNSIGNED_INT ? (uchar)(*(const unsigned int*)value ) :
+                         argType == Param::UINT64 ? (uchar)(*(const uint64*)value ) :
+                         argType == Param::UCHAR ? (uchar)(*(const uchar*)value ) :
+                         (int)(is_ok = false);
+
+            if (!is_ok)
+            {
+                CV_Error(CV_StsBadArg, "Wrong argument type in the setter");
+            }
+            if( p->setter )
+                (algo->*f.set_uchar)(val);
+            else
+                *(uchar*)((uchar*)algo + p->offset) = val;
+        }
+        else
+            CV_Error(CV_StsBadArg, "Wrong parameter type in the setter");
     }
     else if( argType == Param::STRING )
     {
@@ -713,11 +903,12 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argTyp
     GetSetParam f;
     f.get_int = p->getter;
 
-    if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL )
+    if( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::SHORT
+            || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR)
     {
         if( p->type == Param::INT )
         {
-            if (!( argType == Param::INT || argType == Param::REAL ))
+            if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
             {
                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
                 CV_Error(CV_StsBadArg, message);
@@ -726,8 +917,19 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argTyp
 
             if( argType == Param::INT )
                 *(int*)value = val;
-            else
+            else if ( argType == Param::REAL )
                 *(double*)value = val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = val;
+            else if ( argType == Param::UNSIGNED_INT )
+                *(unsigned int*)value = val;
+            else if ( argType == Param::UINT64 )
+                *(uint64*)value = val;
+            else if ( argType == Param::UCHAR)
+                *(uchar*)value = val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
+
         }
         else if( p->type == Param::SHORT )
         {
@@ -742,7 +944,7 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argTyp
         }
         else if( p->type == Param::BOOLEAN )
         {
-            if (!( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL ))
+            if (!( argType == Param::INT || argType == Param::BOOLEAN || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
             {
                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
                 CV_Error(CV_StsBadArg, message);
@@ -753,20 +955,127 @@ void AlgorithmInfo::get(const Algorithm* algo, const char* parameter, int argTyp
                 *(int*)value = (int)val;
             else if( argType == Param::BOOLEAN )
                 *(bool*)value = val;
-            else
+            else if ( argType == Param::REAL )
                 *(double*)value = (int)val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = (int)val;
+            else if ( argType == Param::UNSIGNED_INT )
+                *(unsigned int*)value = (int)val;
+            else if ( argType == Param::UINT64 )
+                *(uint64*)value = (int)val;
+            else if ( argType == Param::UCHAR)
+                *(uchar*)value = (int)val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
         }
-        else
+        else if( p->type == Param::REAL )
         {
-            if( argType != Param::REAL )
+            if(!( argType == Param::REAL || argType == Param::FLOAT))
             {
                 string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
                 CV_Error(CV_StsBadArg, message);
             }
             double val = p->getter ? (algo->*f.get_double)() : *(double*)((uchar*)algo + p->offset);
 
-            *(double*)value = val;
+            if ( argType == Param::REAL )
+                *(double*)value = val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = (float)val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
+        }
+        else if( p->type == Param::FLOAT )
+        {
+            if(!( argType == Param::REAL || argType == Param::FLOAT))
+            {
+                string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
+                CV_Error(CV_StsBadArg, message);
+            }
+            float val = p->getter ? (algo->*f.get_float)() : *(float*)((uchar*)algo + p->offset);
+
+            if ( argType == Param::REAL )
+                *(double*)value = (double)val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = (float)val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
         }
+        else if( p->type == Param::UNSIGNED_INT )
+        {
+            if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
+            {
+                string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
+                CV_Error(CV_StsBadArg, message);
+            }
+            unsigned int val = p->getter ? (algo->*f.get_uint)() : *(unsigned int*)((uchar*)algo + p->offset);
+
+            if( argType == Param::INT )
+                *(int*)value = val;
+            else if ( argType == Param::REAL )
+                *(double*)value = val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = val;
+            else if ( argType == Param::UNSIGNED_INT )
+                *(unsigned int*)value = val;
+            else if ( argType == Param::UINT64 )
+                *(uint64*)value = val;
+            else if ( argType == Param::UCHAR)
+                *(uchar*)value = val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
+        }
+        else if( p->type == Param::UINT64 )
+        {
+            if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
+            {
+                string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
+                CV_Error(CV_StsBadArg, message);
+            }
+            uint64 val = p->getter ? (algo->*f.get_uint64)() : *(uint64*)((uchar*)algo + p->offset);
+
+            if( argType == Param::INT )
+                *(int*)value = val;
+            else if ( argType == Param::REAL )
+                *(double*)value = val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = val;
+            else if ( argType == Param::UNSIGNED_INT )
+                *(unsigned int*)value = val;
+            else if ( argType == Param::UINT64 )
+                *(uint64*)value = val;
+            else if ( argType == Param::UCHAR)
+                *(uchar*)value = val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
+
+        }
+        else if( p->type == Param::UCHAR )
+        {
+            if (!( argType == Param::INT || argType == Param::REAL || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64 || argType == Param::UCHAR))
+            {
+                string message = getErrorMessageForWrongArgumentInGetter(algo->name(), parameter, p->type, argType);
+                CV_Error(CV_StsBadArg, message);
+            }
+            uchar val = p->getter ? (algo->*f.get_uchar)() : *(uchar*)((uchar*)algo + p->offset);
+
+            if( argType == Param::INT )
+                *(int*)value = val;
+            else if ( argType == Param::REAL )
+                *(double*)value = val;
+            else if ( argType == Param::FLOAT)
+                *(float*)value = val;
+            else if ( argType == Param::UNSIGNED_INT )
+                *(unsigned int*)value = val;
+            else if ( argType == Param::UINT64 )
+                *(uint64*)value = val;
+            else if ( argType == Param::UCHAR)
+                *(uchar*)value = val;
+            else
+                CV_Error(CV_StsBadArg, "Wrong argument type");
+
+        }
+        else
+            CV_Error(CV_StsBadArg, "Unknown/unsupported parameter type");
     }
     else if( argType == Param::STRING )
     {
@@ -852,7 +1161,9 @@ void AlgorithmInfo::addParam_(Algorithm& algo, const char* parameter, int argTyp
     CV_Assert( argType == Param::INT || argType == Param::BOOLEAN ||
                argType == Param::REAL || argType == Param::STRING ||
                argType == Param::MAT || argType == Param::MAT_VECTOR ||
-               argType == Param::ALGORITHM || argType == Param::SHORT );
+               argType == Param::ALGORITHM || argType == Param::SHORT
+               || argType == Param::FLOAT || argType == Param::UNSIGNED_INT || argType == Param::UINT64
+               || argType == Param::UCHAR);
     data->params.add(string(parameter), Param(argType, readOnly,
                      (int)((size_t)value - (size_t)(void*)&algo),
                      getter, setter, help));
@@ -939,6 +1250,46 @@ void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
               (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
 }
 
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+                             float& value, bool readOnly,
+                             float (Algorithm::*getter)(),
+                             void (Algorithm::*setter)(float),
+                             const string& help)
+{
+    addParam_(algo, parameter, ParamType<float>::type, &value, readOnly,
+              (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
+}
+
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+                             unsigned int& value, bool readOnly,
+                             unsigned int (Algorithm::*getter)(),
+                             void (Algorithm::*setter)(unsigned int),
+                             const string& help)
+{
+    addParam_(algo, parameter, ParamType<unsigned int>::type, &value, readOnly,
+              (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
+}
+
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+                             uint64& value, bool readOnly,
+                             uint64 (Algorithm::*getter)(),
+                             void (Algorithm::*setter)(uint64),
+                             const string& help)
+{
+    addParam_(algo, parameter, ParamType<uint64>::type, &value, readOnly,
+              (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
+}
+
+void AlgorithmInfo::addParam(Algorithm& algo, const char* parameter,
+                             uchar& value, bool readOnly,
+                             uchar (Algorithm::*getter)(),
+                             void (Algorithm::*setter)(uchar),
+                             const string& help)
+{
+    addParam_(algo, parameter, ParamType<uchar>::type, &value, readOnly,
+              (Algorithm::Getter)getter, (Algorithm::Setter)setter, help);
+}
+
 }
 
 /* End of file. */
index e135087..8d644a3 100644 (file)
@@ -658,6 +658,7 @@ protected:
   virtual void findBlobs(const Mat &image, const Mat &binaryImage, vector<Center> &centers) const;
 
   Params params;
+  AlgorithmInfo* info() const;
 };
 
 
index 1e1b0ca..a50b089 100644 (file)
@@ -130,6 +130,26 @@ CV_INIT_ALGORITHM(GFTTDetector, "Feature2D.GFTT",
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+CV_INIT_ALGORITHM(SimpleBlobDetector, "Feature2D.SimpleBlob",
+                  obj.info()->addParam(obj, "thresholdStep",    obj.params.thresholdStep);
+                  obj.info()->addParam(obj, "minThreshold",     obj.params.minThreshold);
+                  obj.info()->addParam(obj, "maxThreshold",     obj.params.maxThreshold);
+                  obj.info()->addParam(obj, "minRepeatability", obj.params.minRepeatability);
+                  obj.info()->addParam(obj, "minDistBetweenBlobs", obj.params.minDistBetweenBlobs);
+                  obj.info()->addParam(obj, "filterByColor",    obj.params.filterByColor);
+                  obj.info()->addParam(obj, "blobColor",        obj.params.blobColor);
+                  obj.info()->addParam(obj, "filterByArea",     obj.params.filterByArea);
+                  obj.info()->addParam(obj, "maxArea",          obj.params.maxArea);
+                  obj.info()->addParam(obj, "filterByCircularity", obj.params.filterByCircularity);
+                  obj.info()->addParam(obj, "maxCircularity",   obj.params.maxCircularity);
+                  obj.info()->addParam(obj, "filterByInertia",  obj.params.filterByInertia);
+                  obj.info()->addParam(obj, "maxInertiaRatio",  obj.params.maxInertiaRatio);
+                  obj.info()->addParam(obj, "filterByConvexity", obj.params.filterByConvexity);
+                  obj.info()->addParam(obj, "maxConvexity",     obj.params.maxConvexity);
+                  );
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 class CV_EXPORTS HarrisDetector : public GFTTDetector
 {
 public: