이번 글에서는 키보드와 마우스 이벤트를 처리하는 방법을 알아보겠습니다.
키보드 이벤트 처리는 이전 글에도 많이 나왔던 waitKey 함수를 사용하면 됩니다.
/**
@return 입력된 키
@param delay 키 입력을 기다릴 시간(밀리세컨드), 입력된 값이 0보다 작거나 같으면 무한대로 기다립니다.
*/
int waitKey(int delay = 0);
waitKey의 반환으로 입력된 키에 대한 아스키 코드 값을 반환합니다.
아래 코드는 키 ‘a’, ‘b’를 입력 했을 때 각 키에 대해 출력을 하는 프로그램 입니다.
#include <iostream>
#include "opencv2/opencv.hpp"
#ifdef _DEBUG
#pragma comment(lib, "opencv_world440d.lib")
#else
#pragma comment(lib, "opencv_world440.lib")
#endif
using namespace std;
using namespace cv;
int main()
{
Mat img(512, 512, CV_8UC3, Scalar(255,255,255));
if (img.empty())
{
cerr << "image open error" << endl;
return -1;
}
imshow("img", img);
int iKey = waitKey();
if (iKey == 'a')
cout << "\'a\' Key Input" << endl;
else if (iKey == 'b')
cout << "\'b\' Key Input" << endl;
system("pause");
return 0;
}
마우스 이벤트 처리는 setMouseCallback 함수를 사용하면 됩니다.
/**
@param 마우스 이벤트에 대한 윈도우 이름winname Name of the window.
@param onMouse 마우스 이벤트 콜백 함수
@param userdata 콜백 함수에 전달할 사용자 데이터
*/
void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);
2번째 인자를 보면 cv::MouseCallback 타입으로 되어 있습니다. 정의를 보면 아래와 같습니다.
/**
@param event 마우스 이벤트 타입
@param x 마우스 이벤트 x좌표
@param y 마우스 이벤트 y좌표
@param flags 마우스 이벤트 플래그
@param userdata 사용자 데이터
*/
typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
이것과 동일한 함수를 정의하여 2번째 인자에 입력하시면 됩니다.
첫번째 인자 event와 4번째 인자 flags는 MouseEventTypes와 MouseEventFlags를 참고하시면 됩니다.
//! Mouse Events see cv::MouseCallback
enum MouseEventTypes {
EVENT_MOUSEMOVE = 0, //!< indicates that the mouse pointer has moved over the window.
EVENT_LBUTTONDOWN = 1, //!< indicates that the left mouse button is pressed.
EVENT_RBUTTONDOWN = 2, //!< indicates that the right mouse button is pressed.
EVENT_MBUTTONDOWN = 3, //!< indicates that the middle mouse button is pressed.
EVENT_LBUTTONUP = 4, //!< indicates that left mouse button is released.
EVENT_RBUTTONUP = 5, //!< indicates that right mouse button is released.
EVENT_MBUTTONUP = 6, //!< indicates that middle mouse button is released.
EVENT_LBUTTONDBLCLK = 7, //!< indicates that left mouse button is double clicked.
EVENT_RBUTTONDBLCLK = 8, //!< indicates that right mouse button is double clicked.
EVENT_MBUTTONDBLCLK = 9, //!< indicates that middle mouse button is double clicked.
EVENT_MOUSEWHEEL = 10,//!< positive and negative values mean forward and backward scrolling, respectively.
EVENT_MOUSEHWHEEL = 11 //!< positive and negative values mean right and left scrolling, respectively.
};
//! Mouse Event Flags see cv::MouseCallback
enum MouseEventFlags {
EVENT_FLAG_LBUTTON = 1, //!< indicates that the left mouse button is down.
EVENT_FLAG_RBUTTON = 2, //!< indicates that the right mouse button is down.
EVENT_FLAG_MBUTTON = 4, //!< indicates that the middle mouse button is down.
EVENT_FLAG_CTRLKEY = 8, //!< indicates that CTRL Key is pressed.
EVENT_FLAG_SHIFTKEY = 16,//!< indicates that SHIFT Key is pressed.
EVENT_FLAG_ALTKEY = 32 //!< indicates that ALT Key is pressed.
};
샘플 코드는 아래와 같습니다.
#include <iostream>
#include "opencv2/opencv.hpp"
#ifdef _DEBUG
#pragma comment(lib, "opencv_world440d.lib")
#else
#pragma comment(lib, "opencv_world440.lib")
#endif
using namespace std;
using namespace cv;
void on_MouseEvent(int event, int x, int y, int flags, void* userdata)
{
String sEvent = "";
if (event == EVENT_MOUSEMOVE)
sEvent = "EVENT_MOUSEMOVE";
else if (event == EVENT_LBUTTONDOWN)
sEvent = "EVENT_LBUTTONDOWN";
else if (event == EVENT_RBUTTONDOWN)
sEvent = "EVENT_RBUTTONDOWN";
else if (event == EVENT_MBUTTONDOWN)
sEvent = "EVENT_MBUTTONDOWN";
else if (event == EVENT_LBUTTONUP)
sEvent = "EVENT_LBUTTONUP";
else if (event == EVENT_RBUTTONUP)
sEvent = "EVENT_RBUTTONUP";
else if (event == EVENT_MBUTTONUP)
sEvent = "EVENT_MBUTTONUP";
else if (event == EVENT_LBUTTONDBLCLK)
sEvent = "EVENT_LBUTTONDBLCLK";
else if (event == EVENT_RBUTTONDBLCLK)
sEvent = "EVENT_RBUTTONDBLCLK";
else if (event == EVENT_MBUTTONDBLCLK)
sEvent = "EVENT_MBUTTONDBLCLK";
else if (event == EVENT_MOUSEWHEEL)
sEvent = "EVENT_MOUSEWHEEL";
else if (event == EVENT_MOUSEHWHEEL)
sEvent = "EVENT_MOUSEHWHEEL";
String sPos = "";
sPos = format("x: %d, y: %d", x, y);
cout << sEvent << ", " << sPos << endl;
}
int main()
{
Mat img(512, 512, CV_8UC3, Scalar(255,255,255));
if (img.empty())
{
cerr << "image open error" << endl;
return -1;
}
imshow("img", img);
setMouseCallback("img", on_MouseEvent);
int iKey = waitKey();
if (iKey == 'a')
cout << "\'a\' Key Input" << endl;
else if (iKey == 'b')
cout << "\'b\' Key Input" << endl;
system("pause");
return 0;
}
실행 결과는 아래와 같습니다.
![](https://3001ssw.com/wp-content/uploads/2023/08/녹화_2022_03_12_17_28_40_617-min.gif)