无法创建基于类的OpenCV的mouseCallback函数实现

时间:2013-07-11 09:30:39

标签: c++ class opencv callback mouse

正如标题所示,我在基于类的C ++结构中实现OpenCV的mouseCallback函数时遇到了一些麻烦。请允许我解释一下。我已经定义了一个名为BriskMatching的类,其中我创建了一个名为mouseCallback的成员函数,其中包含OpenCV所需的正确参数(请参阅下面的代码片段)。

**Briskmatching.h**

class BriskMatching
{
public:
    BriskMatching();
    ~BriskMatching();

public:
    void mouseCallback(int event, int x, int y, int flags, void *param);
};

这很好,但是当我尝试通过OpenCV的cv::setMouseCallback函数将此函数设置为指定的鼠标回调函数时,我的问题就出现了。

在我的main函数中,我创建了一个名为briskMatcher的BriskMatching类的实例,然后在设置鼠标回调时,我尝试这样做...

cv::setMouseCallback("Matches", BriskMatching::mouseCallback, &matchesImg);

不幸的是,这会引发错误。

Error   3   error C3867: 'BriskMatching::mouseCallback': function call missing argument list; use '&BriskMatching::mouseCallback' to create a pointer to member c:\users\mobilef\documents\visual studio 2010\projects\opencv_objtracking\opencv_briskmatching\main.cpp 54  1   OpenCV_BriskMatching

我可以通过在static中将mouseCallback函数声明为BriskMatching.h来摆脱这个错误,但是由于我在mouseCallback中引用了许多非静态成员变量,因此我得到了其他错误的全部错误功能

所以我问你们这个问题。我应该如何修改我的代码才能将在BriskMatching类中声明的mouseCallback函数正确传递给cv::setMouseCallback函数?

感谢您提供的所有帮助!

2 个答案:

答案 0 :(得分:12)

由于成员函数采用this指针,因此您需要一个静态包装函数。通常,您使用param参数作为成员函数所属对象的地址,因此最终会得到如下内容:

...
static void mouseCallback(int event, int x, int y, int flags, void *param);

void doMouseCallback(int event, int x, int y, int flags);

然后在mouseCallback

void BriskMatching::mouseCallback(int event, int x, int y, int flags, void *param)
{
    BriskMatching *self = static_cast<BriskMatching*>(param);
    self->doMouseCallback(event, x, y, flags);
}

答案 1 :(得分:0)

我也在使用这个方法,但是我意识到静态助手类非常严格,类型和方法绑定。

仅供进一步参考,我已经定义了一个模板化的自由函数,如下所示:

template<typename TClass, void (TClass::*MouseClickType)(int, int, int, int)>
void FreeOnMouseCallback(int event, int x, int y, int flags, void* ptr)
{
    auto* mcPtr = static_cast<TClass*>(ptr);
    if(mcPtr != NULL)
    {
      (mcPtr->*MouseClickType)(event, x, y, flags);
    }
}

我现在可以使用

调用类中的任意函数(匹配签名,但不是名称)
 cv::setMouseCallback( WindowName, FreeOnMouseCallback<Calibrator, &Calibrator::OnMouseCallback>, this );

如果还需要void * ptr,可能会延长,但我在这里省略了它。