ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 마우스 이벤트
    Programming/OpenCV 2015. 4. 19. 17:38

    CvMouseCallback

    void CvMouseCallback(
    	int    event,
    	int    x,
    	int    y,
    	int    flags,
    	void*  param
    );
    
    • evnet: 마우스 이벤트
    • x, y: 마우스 이벤트가 발생한 x, y 좌표(윈도우 크기와 무관, 영상에서의 픽셀 좌표)
    • flags: 각 비트에 마우스 이벤트가 발생했을 때 키보드 또는 마우스 상태
    • param: 특정 구조체의 포인터를 추가 전달

    마우스 이벤트 종류
    event 값 할당된 정수값
    CV_EVENT_MOUSEMOVE 0
    CV_EVENT_LBUTTONDOWN 1
    CV_EVENT_RBUTTONDOWN 2
    CV_EVENT_MBUTTONDOWN 3
    CV_EVENT_LBUTTONUP 4
    CV_EVENT_RBUTTONUP 5
    CV_EVENT_MBUTTONUP 6
    CV_EVENT_LBUTTONDBLCLK 7
    CV_EVENT_RBUTTONDBLCLK 8
    CV_EVENT_MBUTTONDBLCLK 9


    마우스 이벤트의 flags 종류

    flags 값 할당된 정수값
    CV_EVENT_FLAG_LBUTTON 1
    CV_EVENT_FLAG_RBUTTON 2
    CV_EVENT_FLAG_MBUTTON 4
    CV_EVENT_FLAG_CTRLKEY 8
    CV_EVENT_FLAG_SHIFTKEY 16
    CV_EVENT_FLAG_ALTKEY 32




    cvSetMouseCallback()

    void cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param = NULL );

    마우스 이벤트를 호출한다.
    • window_name: 마우스 이벤트를 호출할 창 이름
    • on_mouse: 마우스 이벤트에 따른 작업을 할 함수의 이름
    • param: 함수에 넘겨줄 특별한 정보, 없으면 NULL

    ex) 1
    // 마우스를 이용하여 화면에 사각형 박스 그리기
    #include "cv.h"
    #include "highgui.h"
    
    // 마우스 콜백 함수 선언
    void my_mouse_callback(int event, int x, int y, int flags, void* param);
    
    CvRect box;
    bool drawing_box = false;
    
    // 영상에 사각형을 그리는 함수
    void draw_box(IplImage* img, CvRect rect)
    {
    	cvRectangle(img, cvPoint(rect.x, rect.y),
    		cvPoint(rect.x + rect.width, rect.y + rect.height),
    		cvScalar(0xff, 0x00, 0x00));
    }
    
    int main(int argc, char* arv[])
    {
    	box = cvRect(-1, -1, 0, 0);
    
    	IplImage* image = cvCreateImage(cvSize(200, 200), IPL_DEPTH_8U, 3);
    	cvZero(image);
    
    	IplImage* temp = cvCloneImage(image);
    
    	cvNamedWindow("Box Example");
    
    	// 콜백 함수 등록
    	// 'param 값으로 현재 작업 중인 영상을 넘겨줌으로서
    	// 콜백 함수 내부에서 이 영상을 이용한 작업을 할 수 있다.
    	cvSetMouseCallback("Box Example", my_mouse_callback, (void*)image);
    
    	// 메인 프로그램 루프
    	// 작업 영상을 'temp' 영상으로 복사하고, 사용자가 그리기를 시작하면
    	// temp 영상에 사각형을 그린다. temp 영상을 화면에 출력하고,
    	// 15ms 동안 키 입력을 기다린다. 그리고 구프를 반복
    	while (1)
    	{
    		cvCopyImage(image, temp);
    		if (drawing_box)draw_box(temp, box);
    		cvShowImage("Box Example", temp);
    		if (cvWaitKey(15) == 27) break;
    	}
    
    	// 마무리
    	cvReleaseImage(&image);
    	cvReleaseImage(&temp);
    	cvDestroyWindow("Box Example");
    }
    
    // 마우스 콜백 함수
    // 사용자가 마우스 왼쪽 버튼을 누르면 사각형 그린다
    // 마우스 버튼을 누른 채 드래그하면 사각형 크기를 변화
    // 마우스 버튼을 떼어놓으면 최종적으로 영상에 사각형을 그린다.
    
    void my_mouse_callback(int event, int x, int y, int flags, void* param)
    {
    	IplImage* image = (IplImage*)param;
    
    	switch (event)
    	{
    	case CV_EVENT_MOUSEMOVE:
    	{
    		if (drawing_box)
    		{
    			box.width = x - box.x;
    			box.height = y - box.y;
    		}
    	}
    		break;
    	case CV_EVENT_LBUTTONDOWN:
    	{
    		drawing_box = true;
    		box = cvRect(x, y, 0, 0);
    	}
    		break;
    	case CV_EVENT_LBUTTONUP:
    	{
    		drawing_box = false;
    		if (box.width < 0)
    		{
    			box.x += box.width;
    			box.width *= -1;
    		}
    		if (box.height < 0)
    		{
    			box.y += box.height;
    			box.height *= -1;
    		}
    		draw_box(image, box);
    	}
    		break;
    	}
    }









    ex) 2

    #include "cv.h"
    #include "highgui.h"
    
    void on_mouseEvent(int event, int x, int y, int flags, void* param); 
    
    int main()
    {
    	IplImage* image = cvCreateImage(cvSize(300, 300), IPL_DEPTH_8U, 3);
    
    	cvSet(image, CV_RGB(255, 255, 255));
    	cvNamedWindow("Mouse Event Handling");
    	cvShowImage("Mouse Event Handling", image);
    
    
    	cvSetMouseCallback("Mouse Event Handling", on_mouseEvent, (void*)image);
    	cvWaitKey(0);
    
    	cvDestroyAllWindows();
    
    	cvReleaseImage(&image);
    
    	return 0;
    	
    }
    
    void on_mouseEvent(int event, int x, int y, int flags, void* param)
    	{
    	IplImage *image;
    	image = (IplImage*)param;
    
    
    	switch(event){
    	case 1:
    		if(flags & 16)
    			cvRectangle(image, cvPoint(x-5, y-5), cvPoint(x+5, y+5),
    			CV_RGB(255, 0, 0));
    		else if(flags & 32){
    				CvPoint pts[3] = { {x, y}, {x +10, y}, {x +5, y + 10} };
    				CvPoint *polygon[1] = { pts };
    				int npts[1] = {3};
    				cvPolyLine(image, polygon, npts, 3, 1, CV_RGB(0, 255, 0));	}
    				
    		else{
    			cvCircle(image, cvPoint(x, y), 5, CV_RGB(0, 0, 255), 5);
    		}
    		break;
    	case 2:
    
    		if(flags & 16)
    			cvRectangle(image, cvPoint(x-5, y-5), cvPoint(x+5, y+5),
    			CV_RGB(0, 0, 255));
    		else if(flags & 32)
    			{
    				CvPoint pts[3] = { {x, y}, {x +5, y + 10}, {x -5, y + 10} };
    				CvPoint *polygon[1] = { pts };
    				int npts[1] = {3};
    				cvPolyLine(image, polygon, npts, 3, 1, CV_RGB(0, 255, 0));	}
    		else
    			cvCircle(image, cvPoint(x, y), 5, CV_RGB(255, 0, 0), 5);
    		break;
    	case 7:
    		cvSet(image, CV_RGB(255, 255, 255));
    		break;
    	}
    	cvShowImage("Mouse Event Handling", image);
    }
    








    'Programming > OpenCV' 카테고리의 다른 글

    그리기 함수 - 다각형  (0) 2015.04.19
    그리기 함수 - 직선, 사각형, 원, 타원  (0) 2015.04.19
    cvSplit, cvMerge, cvFlip  (0) 2015.04.14
    IplImage 구조체  (0) 2015.04.12
    CvMat 행렬 구조체  (0) 2015.03.27

    댓글

Designed by Tistory.