void cv::setMouseCallback(const String & winname,
MouseCallback onMouse, // 마우스 콜백 함수 이름
void * userdata = 0);
마우스 콜백 함수란?
typedef void(* cv::MouseCallback) (int event, int x, int y, int flags, void *userdata)
event: 이벤트 종류, MouseEventTypes 상수
x,y: 이벤트 발생 좌표
flags: 이벤트 플래그, MouseEventFlags 상수
userdata: 사용자 지정 데이터
event와flags의 차이
event: 마우스의 행동 (움직이거나, 버튼을 누르거나/떼거나 등...)
flags: 이벤트가 일어났을 때, 마우스의 상태 (왼쪽 버튼이 눌려 있다, Control 버튼이 눌려 있다 등...)
//...
void on_mouse(int event, int x, int y, int flags, void*);
//...
int main()
{
//...
imshow("img", img);
setMouseCallback("img", on_mouse);
//...
주의할 점!
setMouseCallback함수는 꼭namedWindow나imshow로 창을 띄운 뒤 실행해야 한다!!
on_mouse1. 마우스 클릭 시점, 떼는 시점의 좌표 출력void on_mouse(int event, int x, int y, int flags, void*) { switch (event) { case EVENT_LBUTTONDOWN: cout << "EVENT_LBUTTONDOWN: " << x << ", " << y << endl; break; case EVENT_LBUTTONUP: cout << "EVENT_LBUTTONUP: " << x << ", " << y << endl; break; default: break; } }
on_mouse2. 마우스로 그림 그리기void on_mouse(int event, int x, int y, int flags, void*) { switch (event) { case EVENT_LBUTTONDOWN: ptOld = Point(x, y); // 전역 변수 cout << "EVENT_LBUTTONDOWN: " << x << ", " << y << endl; break; case EVENT_LBUTTONUP: cout << "EVENT_LBUTTONUP: " << x << ", " << y << endl; break; case EVENT_MOUSEMOVE: if (flags & EVENT_FLAG_LBUTTON) { line(img, ptOld, Point(x, y), Scalar(0, 255, 255), 3, LINE_AA); ptOld = Point(x, y); imshow("img", img); } break; default: break; } }
if (flags & EVENT_FLAG_LBUTTON)에서==을 쓰면 오류가 생길 수 있으니 주의.
잘 동작한다.
#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
Mat img(500, 500, CV_8UC3, Scalar(0, 0, 0));
Point ptOld;
void on_mouse(int event, int x, int y, int flags, void*);
int main()
{
if (img.empty()) {
cerr << "Image load failed!" << endl;
}
imshow("img", img);
setMouseCallback("img", on_mouse);
waitKey();
destroyAllWindows();
return 0;
}
void on_mouse(int event, int x, int y, int flags, void*)
{
switch (event) {
case EVENT_LBUTTONDOWN:
ptOld = Point(x, y);
cout << "EVENT_LBUTTONDOWN: " << x << ", " << y << endl;
break;
case EVENT_LBUTTONUP:
cout << "EVENT_LBUTTONUP: " << x << ", " << y << endl;
break;
case EVENT_MOUSEMOVE:
if (flags & EVENT_FLAG_LBUTTON) {
line(img, ptOld, Point(x, y), Scalar(0, 255, 255), 3, LINE_AA);
ptOld = Point(x, y);
imshow("img", img);
}
break;
default:
break;
}
}