程序员人生 网站导航

opencv的鼠标以及键值使用

栏目:综合技术时间:2015-03-30 08:41:53

简介

  本章是学习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;  
}  


效果演示

  对应的效果演示以下:
Opencv wt 17 1.jpg
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐