我正在尝试在我的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
真正的程序太大了,不能把它的代码放在这里,为什么我试图简化问题
答案 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的逻辑。鼠标和键盘触发事件以及回调函数等输入将事件传递给实现的功能。