简介
本章是学习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
");
break;
case 'a':
printf("a
");
break;
case 's':
printf("s
");
break;
case 'd':
printf("d
");
break;
case 'q':
printf("exit
");
exit = 1;
break;
default:
printf("c:%d
", c);
}
}
return 0;
}
如代码所示,主要就是waitKey中的参数,小于等于0表示1直等待键值,大于0的表示等待多少毫秒,超时就返回⑴,否则就返回对应的键值。
鼠标响应
#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
", 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对应返回响应参数如上述,需要注意1些组合:比如按下键值CTRL的同时按下鼠标左键拖拽,flag就变成了:9=1+8。如果是按下CTRL+鼠标右键则变成:10=8+2。
最后的void* 类型ustc,就是对应之前传入的str,我传入的str类型为char*,则直接将ustc转回char*便可;如果是传入为0或NULL,则无需处理;如果是
其他类型指针,则转化为对应的类型。
使用实例
这里做1个程序的实例:在图象上画1个根据鼠标拖拽而变化的矩形,然后按下键值‘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
", 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;
}
效果演示
对应的效果演示以下: