简体   繁体   中英

How should I pass a pointer-to-member-function to setMouseCallback in OpenCV?

How can call OnMouse defined in a class in setMouseCallback?

Normally it is like that:

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

Here is my program:

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
}

main.cpp:

How can I use onMouse in setMouseCallback

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

setMouseCallback() does not accept a pointer-to-member-function for the callback, it expects a standalone function instead. As such, if you want to use a class method, you must declare it as static to remove its this pointer.

To access instance members of your class, the callback needs a pointer to an instance of your class. The last parameter of setMouseCallback is a user-provided pointer that is passed to the callback:

SetMouseCallback

Sets mouse handler for the specified window

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

Parameters:
- winname – Window name
- onMouse – Mouse callback. See OpenCV samples, such as https://github.com/Itseez/opencv/tree/master/samples/cpp/ffilldemo.cpp , on how to specify and use the callback.
- userdata – The optional parameter passed to the callback.

You can use that parameter to pass your camh1 object to the callback:

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 );

I would suggest moving setMouseCallback inside the CameraHeight class, where its constructor sets the callback and its destructor clears the callback:

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 );

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

@Remy Lebeau Thanks your answer is right, it helps me a lot.. But after that I get an error that a static member function can't call a member variable of the same class! But I solve it in this way:

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

and to access to CameraHeight instance member inside CameraHeight::onMouse (ex int aa; ):

anInstance->aa;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM