본문 바로가기
Studynote/Computer Science 12

Chapter_03_간단한 그래픽 및 마우스 이벤트

by e.sunie 2018. 11. 3.

Chapter 03. 간단한 그래픽 및 마우스 이벤트


1.영상에 간단한 그래픽 그리기


(1)라인 , 사각형 , 원 , 타원 그리기


  • #define CV_RGB(r,g,b) cvScalar((b),(g),(r))

3채널 컬러 영상의 경우 화소 값이 BGR순으로 저장

~ CV_RGB 매크로 순서대로 입력한 값을 cvScalar를 사용해서 BGR순으로 변경


  • void cvLine(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0);

영상 img에 점 p1-p2까지 color 색상 , thickness 두께로 직선을 그린다 .

line_type=8 : 8이웃 화소 고려

line_type=4 : 4이웃 화소 고려

line_type=CV_AA : 직선이 부드럽게 보이도록 가우시안 필터링을 사용 ~안티에일리징 직선 생성

shift : pt1,pt2의 각 좌표에 비트 이동을 표현


  • void cvrRectangle(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0);

영상 img에 점 pt1, pt2에 의해 정의되는 사각형을 color 색상 , thickness 두께로 그린다 .


  • void cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int line_type=8, int shift=0);

영상 img에 중심점이 center, 반경이 radius인 원을 color 색상 , thickness 두께로 그린다 .


  • void cvEllipse(CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, CvScalar color, int thickness=1, int line_type=8, int shift=0);

영상 img에 center를 중심으로 축의 크기가 axes인 타원을 그린다 .

Angle :x축과의 회전 각도 ~ 회전 타원 draw 가능

start_angle,end_ange : 호 또는 완전히 닫힌 타원 draw 가능


  • void cvEllipseBox(CvArr* img, CvBox2D box, CvScalar color, int thickness=1, int line_type=8, int shift=0);

영상 img에 CvBox2D 자료형의 박스에 내접한 타원을 그린다 .

typedefstructCvBox2D

{

CvPoint2D32f center;// 박스의 중심점

CvSize2D32f size;// 박스의 width, height

floatangle;// 수평축과 length 사이의 각도

}CvBox2D;


  • void cvBoxPoints(CvBox2D box, CvPoint2D32f pt[4]);

박스를 이루는 4점의 좌표를 계산 ~ cvPoint2D32f형의 배열 pt에 저장



라인 , 사각형 그리기

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

// cvSet(dstImage, cvScalarAll(255));

cvSet(dstImage,CV_RGB(255,255,255));

cvRectangle(dstImage,cvPoint(100,100),cvPoint(400,400),CV_RGB(255,0,0));

cvLine(dstImage,cvPoint(400,100),cvPoint(100,400),CV_RGB(0,255,0));

cvLine(dstImage,cvPoint(400,100),cvPoint(100,400),CV_RGB(0,255,0),2,8,1);

// cvLine(dstImage,cvPoint(400/2, 100/2),cvPoint(100/2, 400/2), CV_RGB(0, 255, 0), 2);

cvRectangle(dstImage,cvPoint(400/2,100/2),cvPoint(100/2,400/2),

CV_RGB(0,0,255));

cvNamedWindow("Drawing Graphics",CV_WINDOW_AUTOSIZE);

cvShowImage("Drawing Graphics", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}







원 그리기

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

cvSet(dstImage,CV_RGB(255,255,255));

cvRectangle(dstImage,cvPoint(100,100),cvPoint(400,400),CV_RGB(255,0,0));

cvLine(dstImage,cvPoint(250,100),cvPoint(250,400),CV_RGB(0,255,0));

cvLine(dstImage,cvPoint(100,250),cvPoint(400,250),CV_RGB(0,255,0));

cvCircle(dstImage,cvPoint(250,250),150,CV_RGB(0,0,250));

cvNamedWindow("Drawing Graphics",CV_WINDOW_AUTOSIZE);

cvShowImage("Drawing Graphics", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}






타원 그리기

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

cvSet(dstImage,CV_RGB(255,255,255));

cvLine(dstImage,cvPoint(50,200),cvPoint(450,200),CV_RGB(0,255,0));

cvLine(dstImage,cvPoint(250,100),cvPoint(250,300),CV_RGB(0,255,0));

// cvEllipse(dstImage, cvPoint(250, 200), cvSize(200, 100), 0, 0, 360,

// CV_RGB(0, 0, 250));

cvEllipse(dstImage,cvPoint(250,200),cvSize(200,100),45,0,360,

CV_RGB(255,0,0));

/*

CvBox2D box;

box.center = cvPoint2D32f(250, 200);

box.size = cvSize2D32f(100, 200);

box.angle = 45;

cvEllipseBox(dstImage, box, CV_RGB(255, 0, 255));

CvPoint2D32f pt[4];

cvBoxPoints(box, pt);

CvPoint pt2[4];

int i;

for(i=0; i<4; i++)

{

pt2[i].x = cvRound(pt[i].x);

pt2[i].y = cvRound(pt[i].y);

}

for(i=0; i<3; i++)

cvLine(dstImage, pt2[i], pt2[i+1], CV_RGB(0, 255, 0));

cvLine(dstImage, pt2[3], pt2[0], CV_RGB(0, 255, 0));

*/

cvNamedWindow("Drawing Graphics",CV_WINDOW_AUTOSIZE);

cvShowImage("Drawing Graphics", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}



(2)다각형 그리기 및 채우기


  • void cvPolyLine(CvArr* img, CvPoint** pts, int* npts, int constours, int is_closed, CvScalar color, int thickness=1, int line_type=8, int shift=0);

여러 개의 다각형을 한 번에 그리는 함수

pts : CvPoint 형의 2 중 포인터 ~ 다각형의 포인터

npts : 다각형의 꼭짓점의 수를 저장한 정수형 배열

contours : 다각형의 개수

is_closed=0 : 처음 꼭짓점과 마지막 꼭짓점이 연결되지 않는 개방된 다각선 else 닫힌 다각형



  • void cvRillPoly(CvArr* img, CvPoint** pts, int* npts, int constours, CvScalar color,int line_type=8, int shift=0);

pts 에 주어진 다각형의 내부를 color 로 채우는 함수


  • void cvFillConvexPoly(CvArr* img, CvPoint** pts, int* npts, CvScalar color, int line_type=8, int shift=0);

pts 에 주어진 하나의 볼록다각형을 color 로 채우는 함수


다각형 그리기 및 채우기

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

cvSet(dstImage,CV_RGB(255,255,255));

CvPointpts1[4] = { {100,100}, {200,100}, {200,200}, {100,200} };

CvPointpts2[3] = { {300,200}, {400,100}, {400,200} };

CvPoint*polygon[2] = { pts1, pts2};

intnpts[2] = {4,3};

cvPolyLine(dstImage, polygon, npts,2,1,CV_RGB(0,0,255));// 닫힌 다각형 (is_closed=1)

//cvPolyLine(dstImage, polygon, npts, 2, 0, CV_RGB(0, 0, 255)); // 개방된 다각선 (is_closed=0)

//cvFillPoly(dstImage, polygon, npts, 2, CV_RGB(0, 0, 255));

cvFillConvexPoly(dstImage, polygon[0],4,CV_RGB(0,0,255) );

cvNamedWindow("Drawing Graphics",CV_WINDOW_AUTOSIZE);

cvShowImage("Drawing Graphics", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}






(3) 문자 출력


cvInitFont 함수 : 폰트 초기화 & cvPutText 함수 : 문자 출력


  • void cvInitFont(CvFont* font, int font_face, double hscale, double vscale, double shear=0, int thickness=1, int line_type=8);

font : 초기화될 폰트 구조체의 포인터

font_face : 폰트 이름 ~ CV_FONT_ITALIC 과 비트 논리합을 하여 함께 사용 가능

hscale, vscale : 가로 세로 장명 ~ 1.0 이면 원래 폰트의 가로 세로 크기 그대로

shear : 수직선의 상대적 기울어짐 정도 ~ 0: 기울어지지 않음 , 1:45 도 기울어짐

thickness : 글자의 두께



  • void cvPutText(CvArr* img, const char* text_string, CvPoint org, const CvFont* font, CvScalar color);

영상 img 에 문자열 text_string 를 org 위치에 font 와 color 를 이용해 출력하는 함수

org : 문자열 문자열 출력 기준 위치

text_string : 첫 번째 글자의 왼쪽 아래 좌표


  • void cvGetTextSize(const char* text_string, const CvFont* font, CvSize* text_size, int* baseline);

문자열 text_string 을 font 로 출력시 , 차지하는 영역의 가로 / 세로 크기를 text_size 로 계산

baseline : 기준선 가장 아래 떨어진 글자에 대한 y 좌푠의 상대적 거리


문자열 출력하기

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

cvSet(dstImage,CV_RGB(255,255,255));

CvFontfont;

cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0,1.0);

cvPutText(dstImage,"OpenCV Programming",cvPoint(100,100), &font,

CV_RGB(0,0,0) );

CvSizetext_size;

intbaseline;

cvGetTextSize("OpenCV Programming", &font, &text_size, &baseline );

cvRectangle(dstImage,cvPoint(100,100),cvPoint(100+text_size.width,

100-text_size.height),CV_RGB(255,0,0));

cvNamedWindow("Drawing Graphics",CV_WINDOW_AUTOSIZE);

cvShowImage("Drawing Graphics", dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}





2. 키보드 , 마우스 , 트랙바 이벤트 처리


HIGHGUI 라이브러리 사용


(1) 키보드 이벤트 처리


cvWaitKey 함수

delay<=0 : 키보드에서 키가 눌러질 때 까지 대기

delay>0 : 밀리초 동안 대기 ~ 미리초 동안 키가 안 눌러지면 -1 반환


키보드 이벤트 처리

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

cvSet(dstImage,CV_RGB(255,255,255));

cvNamedWindow("Key Event Handling",CV_WINDOW_AUTOSIZE);

cvShowImage("Key Event Handling", dstImage);

intnKey;

while(1)

{

nKey =cvWaitKey(0);

// printf("%x\n", nKey);

if(nKey ==0x1B)

break;

}

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}




(2) 마우스 이벤트 처리

cvSetMouseCallback 함수로 이벤트 핸들러 함수 지정

→ 핸들러 함수에서 이벤트 처리


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

window_name 인 윈도우에서 발생하는 마우스 이벤트를 처리할 핸들러 함수 on_mouseEvent 로 지정하는 함수

~ 마우스 이벤트 발생마다 핸들러로 지정된 on_mouseEvent 함수 호출

param : 핸들러 함수로 전달될 사용자 정의 인수


  • void on_mouseEvent(int event ,int x, int y, int flags, void* param);

사용자 임의 지정 가능

인수의 자료형과 의미는 지정되어 있다 .

Event : 마우스 이벤트

event

설 명
















Flags : 마우스 이벤트 발생 시 , 마우스 버튼 , CTRL, SHIFT, ALT 키를 눌렀는지 확인

flags

설 명












param : 사용자 정의 인수



마우스 이벤트 처리

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


voidon_mouseEvent(intevent,intx,inty,intflags,void* param);

intmain()

{

IplImage*dstImage;

dstImage =cvCreateImage(cvSize(512,512),IPL_DEPTH_8U,3);

cvSet(dstImage,CV_RGB(255,255,255));

cvNamedWindow("Mouse Event Handling",CV_WINDOW_AUTOSIZE);

cvShowImage("Mouse Event Handling", dstImage);

cvSetMouseCallback("Mouse Event Handling",on_mouseEvent, (void*)dstImage);

cvWaitKey(0);

cvDestroyAllWindows();

cvReleaseImage(&dstImage);

return0;

}


voidon_mouseEvent (intevent,intx,inty,intflags,void* param)

{

IplImage*image;

image = (IplImage*)param;

switch(event)

{

caseCV_EVENT_LBUTTONDOWN:

if(flags &CV_EVENT_FLAG_SHIFTKEY)

cvRectangle(image,cvPoint(x-5, y-5),cvPoint(x+5, y+5),CV_RGB(255,0,0));

else

{

cvCircle(image,cvPoint(x, y),5,CV_RGB(0,0,255),5);

}

break;

caseCV_EVENT_RBUTTONDOWN:

cvCircle(image,cvPoint(x, y),5,CV_RGB(255,0,0),5);

break;

caseCV_EVENT_LBUTTONDBLCLK:

cvSet(image,CV_RGB(255,255,255));

break;

}

cvShowImage("Mouse Event Handling", image);

}




(3) 트랙바 처리


  • int cvCreateTrackbar(const char* trackbar_name, const char*window_name, int* vale, ingcount, CvTrackbarCallback on_change);

지정된 윈도우에 트랙바 생성 함수

trackbar_name : 트랙바 이름

window_name : 트랙바를 붙일 윈도우 이름

value : 트랙바 생성시 슬라이더 위치

count : 트랙바 슬라이더의 최대 위치의 값 ( 최소 : 0)

on_change : 트랙바의 슬라이더가 변경될 때마다 자동 호출 되는 핸들러 함수


  • void on_change(int pos);

트랙바 슬라이더가 변경될 때마다 자동 호출 , pos : 트랙바 슬라이더의 위치


  • int cvGetTrackbarPos(const char* trackbar_name, const char* window_name);

윈도우의 트랙바 슬라이더 위치 값을 반환


  • cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos);

윈도우의 트랙바 슬라이더 위치를 pos 로 설정


트랙바 처리

#include<iostream>

#include<opencv2/opencv.hpp>

#include<opencv2/highgui/highgui.hpp>


voidon_change(intpos =0);

IplImage*srcImage, *dstImage;

intmain()

{

if( (srcImage=cvLoadImage("lena.jpg",CV_LOAD_IMAGE_GRAYSCALE)) ==NULL)

return-1;

dstImage=cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U,1);

cvNamedWindow("srcImage",CV_WINDOW_AUTOSIZE);

cvShowImage("srcImage",srcImage);

cvNamedWindow("dstImage",CV_WINDOW_AUTOSIZE);

cvShowImage("dstImage",dstImage);

intpos=100;

on_change(pos);

cvCreateTrackbar("threshold","dstImage", &pos,255,on_change);

cvWaitKey(0);

cvDestroyWindow("srcImage");

cvDestroyWindow("dstImage");

cvReleaseImage(&srcImage);

cvReleaseImage(&dstImage);

}

// trackbar callback to threshold the image gray value

voidon_change(intpos)

{

// Direct Thresholding

intx, y, s, r;

intnThreshold = pos;

for(y=0; y<srcImage->height; y++)

for(x=0; x<srcImage->width; x++)

{

r =cvRound(cvGetReal2D(srcImage, y, x));

if(r>nThreshold)

s =255;

else

s =0;

cvSetReal2D(dstImage, y, x, s);

}

cvShowImage("dstImage",dstImage);

}




댓글