如何使用cv :: setMouseCallback

时间:2013-01-11 14:29:17

标签: c++ opencv

我正在尝试在我的c ++项目中使用cv :: setMouseCallback。我只是不明白。 让我有一个类Stuff怎么能告诉这个类你有一个框架并在这个框架上运行cv :: setMouseCallback这是我正在尝试做的示例

 class Stuff{
 public: 
Stuff();
void setFrame(cv::Mat); 
void mouse (int,int, int, int,void*);
  private :
cv::Mat frame;
int key;
 };

 Stuff::Stuff(){}

 void Stuff::setFrame(cv::Mat framex){
frame = framex;
 }


  int main (){
Stuff  obj;

cv::Mat frame = cv::imread ("examople.jpg");
char* name;
cv::imshow(name,frame);
cv::setMouseCallback(name,obj.mouse,&frame) // I' stop here because that's exactlly what just don't work 
    }

这是获取的错误消息:

   Stuff::mouse : function call missing argument list; use '&Stuff::mouse ' to create a pointer to member 

真正的程序太大了,不能把它的代码放在这里,为什么我试图简化问题

2 个答案:

答案 0 :(得分:2)

您必须在类中声明一个鼠标处理程序为静态。例如,我有dragger个成员mouser,我希望被调用。我声明了一个帮助器static void mouser,它抛出了收到的void *并调用了成员:

class dragger {

void mouser(int event, int x, int y) {
  current_img = original_img.clone();
  Point P(x, y);
  ...
}
static void mouser(int event, int x, int y, int, void* this_) {
  static_cast<dragger*>(this_)->mouser(event, x, y);
}
以这种方式在dragger构造函数中的

和实例

dragger(string w, Mat m) :
    window_id(w), status(0), original_img(m), /*black(0, 0, 0),*/ K(5, 5)
{
   ...
   setMouseCallback(w, mouser, this);
}

...
}

答案 1 :(得分:1)

首先,您需要在main函数中创建一个命名窗口。 namedWindow( "image", 0 );或类似的东西可以完成这项工作。

鼠标回调函数与frame变量无关,但与窗口关联。在你的情况下,它将是:

char* name = "image";
cv::namedWindow( name, 0 );
cv::setMousCallback(name, obj.mouse,&frame);

回调函数是在窗口上发生事件时调用其他函数的函数。对于鼠标,事件可以是鼠标移动,左,右或中间点击。 Here你可以找到它们的清单,以及很好的解释。

因此,当这个“事件”发生在窗口中时,opencv会在setMouseCallback中调用名称在Stuff::mouse中指定的函数Stuff::mouse( int event, int x, int y, int flags, void* params ) 。如果你定义这样的函数:

switch( event ){
    case CV_EVENT_LBUTTONDOWN:
        //...
        break;

    case CV_EVENT_RBUTTONDOWN:
        //...
        break;

    case CV_EVENT_FLAG_CTRLKEY:
        //...
        break;
}

当它被调用时,事件变量将被填充触发器的值,x和y以及鼠标在图像上的位置等。 如果你想在鼠标功能中传递帧,你可以像在this问题中那样使用它,如果你考虑修正patxiska的答案。

所以使用开关你可以找出它是什么类型的事件:

void*

并将您的框架从cv::Mat转发回{{1}}。

Here你可以找到关于如何使用鼠标回调的Opencv网站的另一个例子。

希望我有所帮助,我暂时没有使用opencv,现在我没有自己的示例源文件。在Opencv GUI中简化了回调,但这是使用任何GUI的逻辑。鼠标和键盘触发事件以及回调函数等输入将事件传递给实现的功能。