setMouseCallback() : 마우스 이벤트 처리

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 : 사용자 지정 데이터

eventflags의 차이

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함수는 꼭 namedWindowimshow로 창을 띄운 뒤 실행해야 한다!!

on_mouse 1. 마우스 클릭 시점, 떼는 시점의 좌표 출력

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_mouse 2. 마우스로 그림 그리기

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;
	}
}

createTrackbar() : 트랙바

profile
올해로 26세

0개의 댓글