本章是学习opencv上键盘和鼠标相应的操纵与实例。
#include <math.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv/cv.h> int main(int agrc, char* argv[]){ int c; int exit = 0; cv::Mat src=cv::imread(argv[1],1); cv::imshow("22", src); while(!exit){ c = cv::waitKey(0); switch(c){ case 'w': printf("w \n"); break; case 'a': printf("a \n"); break; case 's': printf("s \n"); break; case 'd': printf("d \n"); break; case 'q': printf("exit\n"); exit = 1; break; default: printf("c:%d\n", c); } } return 0; }
如代码所示,主要就是waitKey中的参数,小于等于0表示一直等待键值,大于0的表示等待多少毫秒,超时就返回-1,否则就返回对应的键值。
#include <math.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv/cv.h> void on_mouse( int event, int x, int y, int flags, void* ustc) { char *temp = (char *) ustc; printf("temp:%s, event:%d, flags:%d\n", temp, event, flags); } int main(int agrc, char* argv[]){ char str[4] = "tao"; cv::Mat src=cv::imread(argv[1],1); cv::imshow("src",src); cvSetMouseCallback( "src", on_mouse, str); cv::waitKey(0); cv::waitKey(0); cvDestroyAllWindows(); return 0; }
对应代码如上所示,通过函数cvSetMouseCallback,绑定了鼠标事件的相应窗口为:"src",响应函数为:on_mouse,以及可以往该响应函数传入的参数指针:str。 如果没有参数需要传入,可以直接置为0或者NULL。 接着看下它的响应函数on_mouse,先看下该函数的几个参数,首先是:event用来描述鼠标的点击事件。 highgui/highgui_c.h中有定义如下变量:
enum { CV_EVENT_MOUSEMOVE =0, //鼠标移动 CV_EVENT_LBUTTONDOWN =1, //鼠标左键按下 CV_EVENT_RBUTTONDOWN =2, //鼠标右键按下 CV_EVENT_MBUTTONDOWN =3, //鼠标中键按下 CV_EVENT_LBUTTONUP =4, //鼠标左键弹起 CV_EVENT_RBUTTONUP =5, //鼠标右键弹起 CV_EVENT_MBUTTONUP =6, //鼠标中键弹起 CV_EVENT_LBUTTONDBLCLK =7, //鼠标左键双击 CV_EVENT_RBUTTONDBLCLK =8, //鼠标右键双击 CV_EVENT_MBUTTONDBLCLK =9 //鼠标中键双击 };
这些变量就是触发鼠标事件后,对应的event根据鼠标不同操作返回的对应的值,每个值的对应意义如上述。
然后:x,y对应的为鼠标当前坐标。 接着:flag描述鼠标的拖拽事件。 highgui/highgui_c.h中有定义如下变量:
enum { CV_EVENT_FLAG_LBUTTON =1, //鼠标左键拖拽(按下鼠标左键,然后在窗口中拖动鼠标) CV_EVENT_FLAG_RBUTTON =2, //鼠标右键拖拽 CV_EVENT_FLAG_MBUTTON =4, //鼠标中键拖拽 CV_EVENT_FLAG_CTRLKEY =8, //按下键值CTRL不放 CV_EVENT_FLAG_SHIFTKEY =16, //按下键值SHIFT不放 CV_EVENT_FLAG_ALTKEY =32 //按下键值ALT不放 };
flag对应返回响应参数如上述,需要注意一些组合:比如按下键值CTRL的同时按下鼠标左键拖拽,flag就变成了:9=1+8。如果是按下CTRL+鼠标右键则变成:10=8+2。 最后的void* 类型ustc,就是对应之前传入的str,我传入的str类型为char*,则直接将ustc转回char*即可;如果是传入为0或者NULL,则无需处理;如果是 其他类型指针,则转化为对应的类型。
这里做一个程序的实例:在图像上画一个根据鼠标拖拽而变化的矩形,然后按下键值‘C’之后,将对应被画了矩形的位置复制为新图片显示;按下‘q‘键,退出程序。
#include <math.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv/cv.h> using namespace cv; cv::Mat src; char pic_name[20]; int pic_info[4]; void on_mouse( int event, int x, int y, int flags, void* ustc) { if(event == CV_EVENT_LBUTTONDOWN){ pic_info[0] = x; /*width1*/ pic_info[1] = y; /*height1*/ pic_info[2] = 0; /*width2*/ pic_info[3] = 0; /*height2*/ }else if(event == CV_EVENT_LBUTTONUP){ pic_info[2] = x; pic_info[3] = y; src=cv::imread(pic_name,1); cv::rectangle(src,cvPoint(pic_info[0], pic_info[1]),cvPoint(pic_info[2], pic_info[3]),cvScalar(255,0,0),2); cv::imshow("src",src); } if(flags == CV_EVENT_FLAG_LBUTTON){ pic_info[2] = x; pic_info[3] = y; src=cv::imread(pic_name,1); cv::rectangle(src,cvPoint(pic_info[0], pic_info[1]),cvPoint(pic_info[2], pic_info[3]),cvScalar(255,0,0),2); cv::imshow("src",src); } printf("%d %d %d %d\n", pic_info[0], pic_info[1], pic_info[2], pic_info[3]); } int main(int agrc, char* argv[]){ bool exit = false; char c; cv::Mat imageROI; memcpy(pic_name,argv[1],sizeof(argv[1])); src=cv::imread(pic_name,1); cv::imshow("src",src); cvSetMouseCallback( "src", on_mouse, NULL); while(!exit){ c = cv::waitKey(0); if(c == 'c'){ if((pic_info[0] != 0) && (pic_info[1] != 0) && (pic_info[2] != 0) && (pic_info[3] != 0)){ imageROI = src(cv::Rect(pic_info[0], pic_info[1], pic_info[2]-pic_info[0], pic_info[3]-pic_info[1])); cv::imshow("ROI", imageROI); } }else if(c == 'q'){ exit = true; } } cvDestroyAllWindows(); return 0; }
对应的效果演示如下:
原文地址:http://blog.csdn.net/u011630458/article/details/44081561