我应该如何将指向成员函数的指针传递给 OpenCV 中的 setMouseCallback?

Posted

技术标签:

【中文标题】我应该如何将指向成员函数的指针传递给 OpenCV 中的 setMouseCallback?【英文标题】:How should I pass a pointer-to-member-function to setMouseCallback in OpenCV? 【发布时间】:2016-06-13 15:15:41 【问题描述】:

如何调用setMouseCallback类中定义的OnMouse?

通常是这样的:

cv::setMouseCallback( String, onMouse, 0 );

这是我的程序:

Camera_Height.h:

class CameraHeight


public:
  void onMouse( int, int, int, int, void*);
;

Camera_Height.cpp:

void CameraHeight::onMouse( int event, int x, int y, int, void* )

   //processing

ma​​in.cpp:

如何在 setMouseCallback 中使用 onMouse

CameraHeight camh1;
cv::setMouseCallback( String, onMouse, 0 );

【问题讨论】:

在这种情况下你真的需要使用类实例吗? Camera_Height 是什么?它有什么功能?您是否需要它的多个实例,每个实例都有自己的数据和作用于每个实例数据的回调?如果不是,则不要使用实例;只需使用免费功能。 (或者一个完全静态的类,但是让它成为一个类有什么意义呢?) There you go! @karlphillip 这不在课堂上! 【参考方案1】:

setMouseCallback() 不接受回调的指向成员函数的指针,它需要一个独立的函数。因此,如果要使用类方法,则必须将其声明为static 以删除其this 指针。

要访问类的实例成员,回调需要一个指向类实例的指针。 setMouseCallback的最后一个参数是用户提供的指针,传递给回调:

设置鼠标回调

为指定窗口设置鼠标处理程序

C++:void setMouseCallback(const string& winname, MouseCallback onMouse, void* userdata=0 )

C:void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mouse, void* param=NULL )

Python:cv.SetMouseCallback(windowName, onMouse, param=None) → None

参数: - winname – 窗口名称 - onMouse – 鼠标回调。请参阅 OpenCV 示例,例如 https://github.com/Itseez/opencv/tree/master/samples/cpp/ffilldemo.cpp,了解如何指定和使用回调。 - userdata - 传递给回调的可选参数。

您可以使用该参数将您的 camh1 对象传递给回调:

Camera_Height.h:

class CameraHeight

public:
  static void onMouse( int evt, int x, int y, int flags, void* param );
;

Camera_Height.cpp:

void CameraHeight::onMouse( int evt, int x, int y, int flags, void* param )

   CameraHeight *pThis = (CameraHeight*) param; 
   // use pThis as needed...

main.cpp:

CameraHeight camh1;
cv::setMouseCallback( String, &CameraHeight::onMouse, &camh1 );

我建议将setMouseCallback 移动到CameraHeight 类中,其构造函数设置回调,而其析构函数清除回调:

Camera_Height.h:

class CameraHeight

private:
   string m_winname;
   static void onMouse( int evt, int x, int y, int flags, void* param );
public:
  CameraHeight(const string &winname);
  ~CameraHeight();
;

Camera_Height.cpp:

CameraHeight::CameraHeight(const string &winname)
    : m_winname(winname)

    cv::setMouseCallback(m_winname, &CameraHeight::onMouse, this);


CameraHeight::~CameraHeight()

    cv::setMouseCallback(m_winname, NULL, 0);


void CameraHeight::onMouse( int evt, int x, int y, int flags, void* param )

   CameraHeight *pThis = (CameraHeight*) param; 
   // use pThis as needed...

main.cpp:

CameraHeight camh1( String );

【讨论】:

【参考方案2】:

您应该将onMouse 设为静态,然后将其命名为:&CameraHeight::onMouse

【讨论】:

这可能会使事情变得更糟,而不是更好。 ...这仅在函数不需要任何实例数据或将实例作为用户指针传递等情况下才有用。无论哪种方式,它似乎都没有回答如上所述的问题。 @underscore_d 实际上,如果您需要对象数据,通常会传递对象指针。 @LightnessRacesinOrbit 这取决于 OP 是否需要实例数据。 ...这里的回调似乎没有提供用户数据指针。所以这似乎是不行的。【参考方案3】:

@雷米勒博 谢谢你的回答是对的,它对我有很大帮助.. 但是在那之后我得到一个静态成员函数不能调用同一个类的成员变量的错误! 但是我是这样解决的:

void CameraHeight::onMouse( int event, int x, int y, int flags, void* param )  
    CameraHeight *anInstance = static_cast<CameraHeight *>(param); 
  

并访问 CameraHeight::onMouse(例如 int aa;)内的 CameraHeight 实例成员:

anInstance->aa;

【讨论】:

以上是关于我应该如何将指向成员函数的指针传递给 OpenCV 中的 setMouseCallback?的主要内容,如果未能解决你的问题,请参考以下文章

将指向外部类模板的成员函数的指针传递给嵌套类

C++成员函数指针指向全局函数指针

如何将函数指针传递给成员函数c++?

将指向 int 数组的指针传递给成员函数,错误:数组下标的无效类型“int [int]”

在 C++ 中将指向基类的指针传递给派生类的成员函数

工厂:如何将临时智能指针传递给函数。 C++