waitKey()
: 키 입력을 확인하기 위해 사용하는 함수
💡
int waitKey(int delay = 0);
- delay : 키 입력을 기다릴 시간(밀리초 단위), delay≤0 이면 무한히 기다림
- 반환값 : 눌러진 키 값, 지정한 시간 동안 키가 눌리지 않았으면 -1 반환
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(void)
{
Mat img = imread("lenna.bmp");
if (img.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
namedWindow("img");
imshow("img", img);
while (true) {
int keycode = waitKey();
if (keycode == 'i' || keycode == 'I') {
img = ~img;
imshow("img", img);
}
else if (keycode == 27 || keycode == 'q' || keycode == 'Q') {
break;
}
}
return 0;
}
waitKey()를 사용해 특정 키가 입력될 때마다 영상을 반전시켜 보여주는 예
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(void)
{
Mat img = imread("lenna.bmp");
if (img.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
namedWindow("img");
imshow("img", img);
while (true) {
int keycode = waitKey();
if (keycode == 'i' || keycode == 'I') {
img = ~img;
imshow("img", img);
}
else if (keycode == 27 || keycode == 'q' || keycode == 'Q') {
break;
}
}
return 0;
}
❓ 윈도우에서 특수 키 처리
f1, f2, …, f12, ←, → 등으 ㅣ특수 키 입력은 waitKey()로 불가능
→waitKeyEx()
함수 사용
int waktKeyEx(int delay = 0);
setMouseCallback()
: 키 입력을 확인하기 위해 사용하는 함수
OpenCV에 의해 만들어진 창에서 마우스 클릭에 반응하거나 마우스를 드래그하여 영상에 그림을 그리는 등의 동작을 수행할 수 있음
→ 우선 마우스 콜백 함수를 등록하고, 마우스 콜백 함수에 마우스 이벤트를 처리하는 코드 추가
💡
setMouseCallback(const String& winname, MouseCallback onMouse, void& userdata = 0);
• winname | 마우스 이벤트 처리를 할 창의 이름 |
---|---|
• onMouse | 마우스 이벤트 처리를 위한 콜백 함수 이름 |
• userdata | 콜백 함수에 전달할 사용자 데이터의 포인터 |
setMouseCallback() 함수는 winname 창에서 마우스 이벤트가 발생하면, onMouse로 등록된 콜백 함수가 자동으로 호출됨. userdata에는 사용자가 마우스 콜백 함수에 전달하고 싶은 데이터를 void* 형식으로 전달
MouseCallback()
: 마우스 이벤트를 처리하는 코드 추가
💡
typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
• event | MouseEventTypes로 정의된 열거형 상수중 하나 전달 |
---|---|
• x | 마우스 이벤트가 발생한 위치의 x좌표 |
• y | 마우스 이벤트가 발생한 위치의 y좌표 |
• flags | 마우스 이벤트가 발생할 때의 마우스 또는 키보드의 상태 정보 |
MouseEventFlags 열거형 상수의 논리합 조합 전달 | |
• userdata | setMouseCallback() 함수에서 설정한 사용자 데이터의 포인터 만약 설정값이 없었다면, 항상 0(NULL)이 전달됨 |
▼ MouseEventTypes 열거형 상수
MouseEventTypes 열거형 상수 | 값 | 설명 |
---|---|---|
EVENT_MOUSEMOVE | 0 | 마우스가 창 위에서 움직이는 경우 |
EVENT_LBUTTONDOWN | 1 | 마우스 왼쪽 버튼을 누른 경우 |
EVENT_RBUTTONDOWN | 2 | 마우스 오른쪽 버튼을 누른 경우 |
EVENT_MBUTTONDOWN | 3 | 마우스 가운데 버튼을 누른 경우 |
EVENT_LBUTTONUP | 4 | 마우스 왼쪽 버튼을 떼는 경우 |
EVENT_RBUTTONUP | 5 | 마우스 오른쪽 버튼을 떼는 경우 |
EVENT_MBUTTONUP | 6 | 마우스 가운데 버튼을 떼는 경우 |
EVENT_LBUTTONDBLCLK | 7 | 마우스 왼쪽 버튼을 더블클릭하는 경우 |
EVENT_RBUTTONDBLCLK | 8 | 마우스 오른쪽 버튼을 더블클릭하는 경우 |
EVENT_MBUTTONDBLCLK | 9 | 마우스 가운데 버튼을 더블클릭하는 경우 |
EVENT_MOUSEWHEEL | 10 | 마우스 휠을 앞뒤로 돌리는 경우 |
EVENT_MOUSEHWHEEL | 11 | 마우스 휠을 좌우로 움직이는 경우 |
▼ MouseEventFlags 열거형 상수
MouseEventFlags 열거형 상수 | 값 | 설명 |
---|---|---|
EVENT_FLAG_LBUTTON | 1 | 마우스 왼쪽 버튼이 눌려 있음 |
EVENT_FLAG_RBUTTON | 2 | 마우스 오른쪽 버튼이 눌려 있음 |
EVENT_FLAG_MBUTTON | 4 | 마우스 가운데 버튼이 눌려 있음 |
EVENT_FLAG_CTRLKEY | 8 | Ctrl 키가 눌려 있음 |
EVENT_FLAG_SHIFTKEY | 16 | Shift 키가 눌려 있음 |
EVENT_FLAG_ALTKEY | 32 | Alt 키가 눌려 있음 |
마우스 이벤트 처리 예제
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat img;
Point ptOld;
void on_mouse(int event, int x, int y, int flags, void*);
int main(void)
{
img = imread("lenna.bmp");
if (img.empty()) {
cerr << "Image load failed!" << endl;
return -1;
}
namedWindow("img");
setMouseCallback("img", on_mouse);
imshow("img", img);
waitKey(0);
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), 2);
imshow("img", img);
ptOld = Point(x, y);
}
break;
default:
break;
}
}
ptOld
변수를 전역 변수 형태로 선언ptOld
: 마우스 왼쪽 버튼이 눌린 좌표 저장, ptOld는 마우스가 움직인 궤적을 그릴 때 사용if (flags & EVENT_FLAG_LBUTTON)
→ flags 인자에 EVENT_FLAG_LBUTTON
비트가 설정되어 있 는지 확인하기 위해 & 연산자 사용OpenCV에서 지공하는 범용적인 GUI
트랙바는 슬라이더 컨트롤(slider control)이라고도 부르며, 영상 출력 창에 부착되어 프로그램 동작 중에 사용자가 지정된 범위 안의 값을 선택
createTrackbar()
: 트랙바 생성 함수
💡
int createTrackbar(const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange = 0, void* userdata = 0);
콜백 함수는 트랙 바의 바를 조절할 때 위치한 값을 전달합니다.
• trackbarname | 트랙바 이름 |
---|---|
• winname | 트랙바를 생성할 창 이름 |
• value | 트랙바 최소값(초기값) |
• count | 트랙바 최대 위치 |
• onChange | 트랙바 위치가 변경될 때마다 호출되게 만들 콜백 함수 이름(함수의 포인터) 만약 NULL을 지정하면 콜백 함수는 호출되지 않고 value로 지정한 변수 값만 갱신 |
• userdata | 트랙바 콜백 함수에 전달할 사용자 데이터의 포인터 |
• 반환값 | 정상 동작하면 1, 실패하면 0 반환 |
정수형 변수를 하나 만들고, 그 변수의 주소를 value 인자로 설정하면, 트랙바 위치가 해당 변수에 자동으로 저장됨
TrackbarCallback
함수💡
typedef void (*TrackbarCallback)(int pos, void* userdata);
- pos : 현재 트랙바의 위치 정보 전달
- userdata : createTrackbar() 함수에서 지정한 사용자 데이터 포인터 값
트랙바를 이용한 그레이스케일 레벨 표현 (0~16값 선택)
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
void on_level_change(int pos, void* userdata);
int main(void)
{
Mat img = Mat::zeros(400, 400, CV_8UC1);
namedWindow("image");
createTrackbar("level", "image", 0, 16, on_level_change, (void*)&img);
imshow("image", img);
waitKey(0);
return 0;
}
void on_level_change(int pos, void* userdata)
{
Mat img = *(Mat*)userdata;
img.setTo(pos * 16);
imshow("image", img);
}
트랙바 콜백 함수로 등록된 on_level_change() 함수는 사용자가 선택한 트랙바 위치에 16을 곱하여 영상의 전체 픽셀 값으로 설정한다. 즉, 이 예제 프로그램은 그레이스케일 레벨을 16단계로 보여 준다.
getTrackbarPos()
: 트랙바의 현재 위치 반환
💡
int getTrackbarPos(const String& trackbarname, const String& winname);
• trackbarname | 트랙바 이름 |
---|---|
• winname | 트랙바가 부착되어 있는 창 이름 |
• 반환값 | 지정한 트랙바의 현재 위치 |
setTrackbarPos()
: 프로그램 동작 중 트랙바 위치를 강제로 특정 위치로 옮김
💡
void setTrackbarPos(const String& trackbarname, const String& winname, int pos);
• trackbarname | 트랙바 이름 |
---|---|
• winname | 트랙바가 부착되어 있는 창 이름 |
• pos | 트랙바를 이동할 위치 |