5

我正在尝试在我的 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 

真正的程序太大了,无法将其代码放在这里,这就是为什么我要简化问题

4

2 回答 2

3

您必须在类中将鼠标处理程序声明为静态。例如,我有一个draggerwith a member mouser,我想被调用。我声明了一个 helper 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);
}

...
}
于 2013-01-11T16:01:12.463 回答
1

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

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

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

回调是在窗口上发生事件时调用其他函数的函数。对于鼠标,事件可以是鼠标移动、左键、右键或中键。在这里您可以找到它们的列表以及很好的解释。

因此,当此“事件”发生在窗口中时,opencv 会调用setMouseCallback在您的情况下作为参数指定名称的函数Stuff::mouse。如果你这样定义函数:

Stuff::mouse( int event, int x, int y, int flags, void* params )

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

因此,通过开关,您可以找出它是什么类型的事件:

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

    case CV_EVENT_RBUTTONDOWN:
        //...
        break;

    case CV_EVENT_FLAG_CTRLKEY:
        //...
        break;
}

并将您的框架从void*后面转换为cv::Mat.

在这里,您可以找到有关如何使用鼠标回调的 Opencv 网站的另一个示例。

希望我能帮上忙,我有一段时间没有使用 opencv 了,现在也没有我的示例源文件。回调在 Opencv GUI 中得到了简化,但这是使用任何 GUI 的逻辑。诸如鼠标和键盘触发事件之类的输入以及回调函数将事件传递给您的实现的函数。

于 2013-01-11T15:22:28.647 回答