TOP
在opencv学习中教程中的鼠标回调函数的使用,都是在主函数中调用,但在自定义类中调用该函数时,会出现参数的类型与形参不匹配问题。最后在stackoverflow中找到了一些解决办法。
鼠标调用的函数为:
1 /** @brief Sets mouse handler for the specified window 2 3 @param winname Name of the window. 4 @param onMouse Callback function for mouse events. See OpenCV samples on how to specify and use the callback. 5 @param userdata The optional parameter passed to the callback. 6 */ 7 8 CV_EXPORTS void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);
ˇ参数1:winname即为在哪一个窗口调用该函数
ˇ参数2:onMouse是一个函数指针
ˇ参数3:用户传递的数据
其中第二个参数即为我们对鼠标实际操作的地方,在主函数调用的话正常定义调用就可以了,但是当在自定义类中定以回调函数时,便会报参数类型与形参类型不匹配,来看一下回调函数的原型:
1 /** @brief Callback function for mouse events. see cv::setMouseCallback 2 @param event one of the cv::MouseEventTypes constants. 3 @param x The x-coordinate of the mouse event. 4 @param y The y-coordinate of the mouse event. 5 @param flags one of the cv::MouseEventFlags constants. 6 @param userdata The optional parameter. 7 */ 8 9 typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
这里是一个宏定义,将一个函数指针定义宏名为MouseCallback,为了解决参数类型与形参(cv::MouseCallback)不匹配问题,在private中定义一个友元函数,当然也有使用全局变量的方法,但我更倾向于这种方法。
1 class App 2 { 3 public: 4 App(); 5 ~App(); 6 void setWin(const std::string& _winname); 7 ... 8 private: 9 void on_mouse_internal(int ev, int x, int y); 10 11 std::string winname; 12 13 friend void on_mouse(int ev, int x, int y, int, void* obj); 14 ... 15 }; 16 void on_mouse(int ev, int x, int y, int, void* obj) 17 { 18 App* app = static_cast<App*>(obj); 19 if (app) 20 app->on_mouse_internal(ev, x, y); 21 } 22 23 App::App() 24 { 25 ... 26 } 27 28 App::~App() 29 { 30 ... 31 } 32 33 void App::setWin(const std::string& _winname) 34 { 35 cv::namedWindow(_winname); 36 this->winname = _winname; 37 cv::setMouseCallback(winname, on_mouse, this); 38 } 39 40 void App::on_mouse_internal(int ev, int x, int y) 41 { 42 std::cout << "X:" << x << ";Y:" << y << std::endl; 43 // here you can specify class members 44 } 45 ...
当然这里友元函数要记得声明
ε=(´ο`*)))唉 学习之路永无止境