일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- Artificial Intelligence
- Machine Learning
- 빅데이터
- MongoDB
- 빅데이타
- 데이터 과학
- 몽고디비
- nodeJS
- WebGL
- 김양재 목사님
- 우리들교회
- data science
- No SQL
- 빅 데이타
- 인공지능
- R
- 주일설교
- Statistics
- node.js
- 확률
- openCV
- 딥러닝
- 빅 데이터
- Big Data
- Deep learning
- 김양재
- probability
- 김양재 목사
- 통계
- c++
Archives
- Today
- Total
Scientific Computing & Data Science
[OpenCV] 이미지 윈도우 상에서 마우스 이벤트 감지하기 본문
이번 포스팅에서는 OpenCV의 마우스 콜백(Callback) 함수를 이용하여 이미지 윈도우 상에서 마우스 이벤트를 감지하는 방법에 대하여 알아보도록 하겠습니다.
OpenCV의 마우스 콜백함수는 setMouseCall 이며, 함수의 프로토타입은 다음과 같습니다:
void cv::setMouseCallback (
const String & winname,
MouseCallback onMouse,
void * userdata = 0
)
파라미터들:
winname 윈도우의 이름
onMouse 마우스 콜백 함수 이름
userdata 콜백에 전달되는 옵션 파라미터
onMouse는 마우스 콜백 함수 이름인데 파라미터들은 다음과 같이 정의됩니다:
void onMouse(
int event,
int x,
int y,
int flags,
void* userdata
)
Parameter |
Description |
event |
마우스 이벤트 타입. EVENT_MOUSEMOVE |
x |
마우스 이벤트의 x좌표 |
y |
마우스 이벤트의 y좌표 |
flags |
마우스 이벤트가 발생할 때의 특정 조건. EVENT_FLAG_LBUTTON |
userdata |
setMouseCallback 함수로 전달되는 포인터 |
Example 1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace std; using namespace cv; /*///////////////////////////////////// @ function: CallBackFunc *////////////////////////////////////// void CallBackFunc( int event, int x, int y, int flags, void* userdata ) { if ( event == EVENT_LBUTTONDOWN ) { std::cout << "Left button of the mouse is clicked - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_RBUTTONDOWN ) { std::cout << "Right button of the mouse is clicked - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_MBUTTONDOWN ) { std::cout << "Middle button of the mouse is clicked - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_MOUSEMOVE ) { std::cout << "Mouse move over the window - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_LBUTTONUP ) { std::cout << "Left button of the mouse is released - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_RBUTTONUP ) { std::cout << "Right button of the mouse is released - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_MBUTTONUP ) { std::cout << "Middle button of the mouse is released - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_LBUTTONDBLCLK ) { std::cout << "Left button of the mouse is double-clicked - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_RBUTTONDBLCLK ) { std::cout << "Right button of the mouse is double-clicked - position (" << x << ", " << y << ")" << std::endl; } else if ( event == EVENT_MBUTTONDBLCLK ) { std::cout << "Middle button of the mouse is double-clicked - position (" << x << ", " << y << ")" << std::endl; } if ( flags & CV_EVENT_FLAG_LBUTTON ) { std::cout << "\tCV_EVENT_FLAG_LBUTTON" << std::endl; } if ( flags & CV_EVENT_FLAG_RBUTTON ) { std::cout << "\tCV_EVENT_FLAG_RBUTTON" << std::endl; } if ( flags & CV_EVENT_FLAG_MBUTTON ) { std::cout << "\tCV_EVENT_FLAG_MBUTTON" << std::endl; } if ( flags & CV_EVENT_FLAG_CTRLKEY ) { std::cout << "\tCV_EVENT_FLAG_CTRLKEY" << std::endl; } if ( flags & CV_EVENT_FLAG_SHIFTKEY ) { std::cout << "\tCV_EVENT_FLAG_SHIFTKEY" << std::endl; } if ( flags & CV_EVENT_FLAG_ALTKEY ) { std::cout << "\tCV_EVENT_FLAG_ALTKEY" << std::endl; } } /*///////////////////////////////////// @ function: main *////////////////////////////////////// int main() { /// Read image from file cv::Mat img = cv::imread( {YOUR_IMAGE_PATH} ); /// if fail to read the image if ( img.empty() ) { std::cout << "Error loading the image" << std::endl; return -1; } /// Create a window cv::namedWindow( "ImageDisplay", 1 ); /// set the callback function for any mouse event cv::setMouseCallback( "ImageDisplay", CallBackFunc, NULL ); /// show the image cv::imshow( "ImageDisplay", img ); /// Wait until user press some key waitKey( 0 ); return 0; } | cs |
Example 2 - FILL DEMO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/imgcodecs.hpp" #include "opencv2/videoio/videoio.hpp" #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace std; using namespace cv; // Global cv::Mat image0, image, gray, mask; int ffillMode = 1; int loDiff = 20, upDiff = 20; int connectivity = 4; int isColor = true; bool useMask = false; int newMaskVal = 255; /*///////////////////////////////////// @ function: help *////////////////////////////////////// static void help() { cout << "\nThis program demonstrated the floodFill() function\n" "Call:\n" "./ffilldemo [image_name -- Default: ../data/fruits.jpg]\n" << endl; cout << "Hot keys: \n" "\tESC - quit the program\n" "\tc - switch color/grayscale mode\n" "\tm - switch mask mode\n" "\tr - restore the original image\n" "\ts - use null-range floodfill\n" "\tf - use gradient floodfill with fixed(absolute) range\n" "\tg - use gradient floodfill with floating(relative) range\n" "\t4 - use 4-connectivity mode\n" "\t8 - use 8-connectivity mode\n" << endl; } /*///////////////////////////////////// @ function: onMouse *////////////////////////////////////// static void onMouse( int event, int x, int y, int, void* ) { if( event != EVENT_LBUTTONDOWN ) return; Point seed = Point(x,y); int lo = ffillMode == 0 ? 0 : loDiff; int up = ffillMode == 0 ? 0 : upDiff; int flags = connectivity + (newMaskVal << 8) + (ffillMode == 1 ? FLOODFILL_FIXED_RANGE : 0); int b = (unsigned)theRNG() & 255; int g = (unsigned)theRNG() & 255; int r = (unsigned)theRNG() & 255; Rect ccomp; cv::Scalar newVal = isColor ? cv::Scalar( b, g, r ) : cv::Scalar( r*0.299 + g*0.587 + b*0.114 ); cv::Mat dst = isColor ? image : gray; int area; if( useMask ) { cv::threshold( mask, mask, 1, 128, THRESH_BINARY ); area = cv::floodFill( dst, mask, seed, newVal, &ccomp, cv::Scalar( lo, lo, lo ), cv::Scalar( up, up, up ), flags ); cv::imshow( "mask", mask ); } else { area = cv::floodFill( dst, seed, newVal, &ccomp, cv::Scalar( lo, lo, lo ), cv::Scalar( up, up, up ), flags ); } cv::imshow( "image", dst ); std::cout << area << " pixels were repainted\n"; } /*///////////////////////////////////// @ function: main *////////////////////////////////////// int main() { cv::Mat image0 = imread( {YOUR_IMAGE_PATH}, 1 ); if( image0.empty() ) { cout << "Image empty. Usage: ffilldemo <image_name>\n"; return 0; } help(); image0.copyTo(image); cv::cvtColor(image0, gray, COLOR_BGR2GRAY); mask.create(image0.rows+2, image0.cols+2, CV_8UC1); namedWindow( "image", 0 ); createTrackbar( "lo_diff", "image", &loDiff, 255, 0 ); createTrackbar( "up_diff", "image", &upDiff, 255, 0 ); setMouseCallback( "image", onMouse, 0 ); for(;;) { imshow( "image", isColor ? image : gray ); int c = waitKey( 0 ); if( (c & 255) == 27 ) { cout << "Exiting ...\n"; break; } switch( (char)c ) { case 'c': if( isColor ) { std::cout << "Grayscale mode is set\n"; cv::cvtColor(image0, gray, COLOR_BGR2GRAY); mask = Scalar::all(0); isColor = false; } else { std::cout << "Color mode is set\n"; image0.copyTo(image); mask = Scalar::all(0); isColor = true; } break; case 'm': if( useMask ) { cv::destroyWindow( "mask" ); useMask = false; } else { cv::namedWindow( "mask", 0 ); mask = Scalar::all( 0 ); cv::imshow( "mask", mask ); useMask = true; } break; case 'r': std::cout << "Original image is restored\n"; image0.copyTo( image ); cv::cvtColor( image, gray, COLOR_BGR2GRAY ); mask = Scalar::all( 0 ); break; case 's': std::cout << "Simple floodfill mode is set\n"; ffillMode = 0; break; case 'f': std::cout << "Fixed Range floodfill mode is set\n"; ffillMode = 1; break; case 'g': std::cout << "Gradient (floating range) floodfill mode is set\n"; ffillMode = 2; break; case '4': std::cout << "4-connectivity mode is set\n"; connectivity = 4; break; case '8': std::cout << "8-connectivity mode is set\n"; connectivity = 8; break; } } return 0; } | cs |
Result
Original |
Ffill |
|
|
Example 3 - ExtractColor
마우스를 클릭한 위치의 컬러 정보를 얻는 예제.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include "opencv2/highgui/highgui.hpp" #include <iostream> using namespace std; using namespace cv; /*///////////////////////////////////// @ function: mouseEvent *////////////////////////////////////// void mouseEvent( int evt, int x, int y, int flags, void* param ) { cv::Mat* rgb = (cv::Mat*) param; if ( evt == CV_EVENT_LBUTTONDOWN ) { printf("%d %d: %d, %d, %d\n", x, y, (int)(*rgb).at<Vec3b>(y, x)[0], (int)(*rgb).at<Vec3b>(y, x)[1], (int)(*rgb).at<Vec3b>(y, x)[2]); } } /*///////////////////////////////////// @ function: main *////////////////////////////////////// int main() { /// Read image from file cv::Mat img = cv::imread( {YOUR_IMAGE_PATH} ); /// if fail to read the image if ( img.empty() ) { std::cout << "Error loading the image" << std::endl; return -1; } /// Create a window cv::namedWindow( "My Window", 1 ); /// set the callback function for any mouse event cv::setMouseCallback( "My Window", mouseEvent, &img ); /// show the image cv::imshow( "My Window", img ); /// Wait until user press some key cv::waitKey(0); return 0; } | cs |
'Programming > OpenCV' 카테고리의 다른 글
[OpenCV] Color Map (0) | 2015.09.27 |
---|---|
[OpenCV] Face Detection & Put Mask on Face (0) | 2015.09.26 |
[OpenCV] Bitwise Operation (0) | 2015.09.20 |
[OpenCV] 2D Convolution / New Filter (0) | 2015.09.16 |
[OpenCV] Canny Edge Detector에 대한 CPU와 CUDA 비교 (0) | 2015.09.02 |
Comments