opencv的滑鼠以及鍵值使用
阿新 • • 發佈:2019-01-01
簡介
本章是學習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;
}
效果演示
對應的效果演示如下: