5

正如标题所示,我在基于类的 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函数将此函数设置为指定的鼠标回调函数时,我的问题就出现了。

在我的主函数中,我创建了一个名为 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

我可以通过将 mouseCallback 函数声明为staticin来消除此错误,BriskMatching.h但是由于我在 mouseCallback 函数中引用了许多非静态成员变量,因此我得到了一大堆其他错误。

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

感谢您在高级方面的所有帮助!

4

2 回答 2

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);
}
于 2013-07-11T09:36:42.370 回答
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,它可能会被扩展,但我在这里省略了它。

于 2014-04-14T15:34:10.063 回答