Ask Your Question
2

Using Setters and Getters in AlgorithmInfo::addParam for Algorithm inheritance

asked 2012-09-07 12:54:58 -0600

cwadding gravatar image

updated 2012-10-02 05:56:23 -0600

V.G. gravatar image

I am working on creating my own algorithm inheriting from cv::Algorithm using the reference from the OpenCV docs. I have created my own classes that inherit from cv::Algorithm with success but I am having difficulty with this one since it has a member m_model which is a stuct from a library that can't be modified because the MyAlgorithm class is wrapping the functionality in this struct.

Anyways, I am trying to reference a member within the struct that is a `uchar[3] so I wrapped it in a cv::Ptr. When I compile my program without and getters or setters on the addParam method

obj.info()->addParam<uchar[3]>(obj, "arrPtr",  *arrPtr, false);

the code compiles fine but I get a runtime error when I try to write an MyAlgorithm object to file because it can't get the data. It is looking for a member variable with the arr name but it doesn't exist. So I defined some getter and setter methods for the arr parameter within the m_model class member.

However, I am not sure how to pass the member function pointers into the addParams method. I know that I can't just pass them into the addParams method like a function like I am currently doing in the code below. I have also tried the following:

obj.info()->addParam<uchar[3]>(obj, "arr",  *arrPtr, false, &MyAlgorithm::getArr, &MyAlgorithm::setArr);

but I get a compile error:

cannot convert parameter 5 from 'cv::Ptr<_Tp> (__thiscall MyAlgorithm::* )(void)' to 'cv::Ptr<_Tp> (__thiscall cv::Algorithm::* )(void)'

Below is a stripped down sample of my source code. Any help would be greatly appreciated.

my_algorithm.h

class MyAlgorithm : public cv::Algorithm    {
public:
    //Other class logic
    cv::Ptr<uchar[3]> getArr();
    void setArr(const cv::Ptr<uchar[3]> &arrPtr);

    virtual cv::AlgorithmInfo* info() const;
protected:
    //define members such as m_model
};
cv::Algorithm* createMyAlgorithm();
cv::AlgorithmInfo& MyAlgorithm_info();

my_algorithm.cpp

cv::Algorithm* createMyAlgorithm()
{
   return new MyAlgorithm();
}

cv::AlgorithmInfo& MyAlgorithm_info() 
{
   static cv::AlgorithmInfo MyAlgorithm_info_var("MyAlgorithm", createMyAlgorithm);
   return MyAlgorithm_info_var;
}

cv::AlgorithmInfo* MyAlgorithm::info() const
{
   static volatile bool initialized = false;

   if( !initialized ) 
   { 
      initialized = true;
      MyAlgorithm obj; 
      cv::Ptr<uchar[3]> *arrPtr = new cv::Ptr<uchar[3]>(&(obj.m_model->arr));
      obj.info()->addParam<uchar[3]>(obj, "arr",  *arrPtr, false, &getArr, &setArr);
   } 
   return &MyAlgorithm_info();
}

cv::Ptr<uchar[3]> MyAlgorithm::getArr(){
   //Logic to get arr
}
void MyAlgorithm::setModMin(const cv::Ptr<uchar[3]> &arrPtr){
   //Logic to set arr
}
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2012-09-19 09:12:45 -0600

cwadding gravatar image

I managed to get the setter and getter for the addParam method to work. The issue was that I needed to perform a static_cast to the parent class like so:

typedef cv::Ptr<uchar[3]> (cv::Algorithm::*ArrGetter)();
typedef void (cv::Algorithm::*ArrSetter)(const cv::Ptr<uchar[3]> &);
obj.info()->addParam<uchar[3]>(obj, "arr",  *arrPtr, false, static_cast<ArrGetter>(&MyAlgorithm::getArr), static_cast<ArrSetter>(&MyAlgorithm::setArr));

However, I also found that OpenCV doesn't know how to handle the read and writes of a uchar[3]. I tried a cv::Vec3b which didn't seem to work either so I settled on a cv::Mat using the setters and getters. So the final solution looks something like this.

my_algorithm.h

class MyAlgorithm : public cv::Algorithm    {
public:
    typedef cv::Mat (cv::Algorithm::*ArrGetter)();
    typedef void (cv::Algorithm::*ArrSetter)(const cv::Mat &);

    //Other class logic
    cv::Mat getArr();
    void setArr(const cv::Mat &arrPtr);

    virtual cv::AlgorithmInfo* info() const;
protected:
    uchar[3] arr;
};
cv::Algorithm* createMyAlgorithm();
cv::AlgorithmInfo& MyAlgorithm_info();

my_algorithm.cpp

cv::AlgorithmInfo* MyAlgorithm::info() const
{
    static volatile bool initialized = false;

    if( !initialized ) 
    { 
        initialized = true;
        MyAlgorithm obj;
        cv::Vec3b arrVec(arr);
        obj.info()->addParam(obj, "arr",  (cv::Mat)arrVec, false, static_cast<ArrGetter>(&MyAlgorithm::getArr), static_cast<ArrSetter>(&MyAlgorithm::setArr));
    } 
    return &MyAlgorithm_info();
}

cv::Mat MyAlgorithm::getArr(){
    cv::Vec3b arrVec(arr);
    return (cv::Mat)arrVec;
}
void MyAlgorithm::setArr(const cv::Mat &arrMat){
    for (int i = 0; i < 3; i++)
        arr[i] = arrMat.at<uchar>(i);
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2012-09-07 12:54:58 -0600

Seen: 949 times

Last updated: Oct 02 '12