증강현실(augmented reality)를 구현하기 위해 카메라로 읽은 영상에 문자나 입체 도형들을 표시할 일이 있습니다. 처음에는 OpenCV 라이브러리를 사용해서 카메라로부터 영상을 읽어들이고, OpenGL로 배경을 투명하게 하여 영상 위에 입체 도형을 그리면 되지 않을까 생각하고 인터넷을 뒤져보았습니다. 그런데 참고할 만한 방법이나 소스를 검색하지 못했습니다. 그래서 OpenGL로 배경을 검게 하여 입체 도형을 그리고 도형만 따 낸 다음 OpenCV 이미지에 겹쳐 그리는 방법을 생각해 보았습니다. 다음 소스코드는 제가 생각한 방법에 대한 구현입니다. OpenCV 이미지에 OpenGL 도형을 그려야 할 경우 참고해 보시기 바랍니다.
VC++ 2008로 작성한 코드:
소스코드에 대해 간단히 설명해 보겠습니다. 주요 기능들은 OpenGL.cpp 파일과 OpenGL.h 파일에 모두 구현되어 있습니다. 이 두 파일을 참고하시기 바랍니다.
먼저 OpenGL에서 배경을 검게 설정하는 부분입니다.
// 배경을 따내기 좋도록 검은 색으로 설정한다.
glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.);
그리고 x,y,z 좌표계와 도형을 그리는 부분입니다.
// x, y, z 축으로 좌표계를 이동하고 회전한다.
glTranslated (x, y, z);
glRotated (yaw , 0, 0, 1); // z-축을 회전축으로 yaw 만큼 회전
glRotated (pitch, 0, 1, 0); // y-축을 회전축으로 pitch 만큼 회전
glRotated (roll , 1, 0, 0); // x-축을 회전축으로 roll 만큼 회전
// x, y, z 좌표 축을 그린다.
glDisable(GL_LIGHTING);
glLineWidth(3);
glColor3d(1, 0, 0);
oglLine (0,0,0, 1,0,0);
glColor3d(0, 1, 0);
oglLine (0,0,0, 0,1,0);
glColor3d(0, 0, 1);
oglLine (0,0,0, 0,0,1);
glEnable(GL_LIGHTING);
// 박스를 그린다.
glColor3d(0.5, 0.5, 0.5);
oglBox (0.5, 0.5, 0.5);
마지막으로 OpenCV로 이미지 파일을 읽어와 마스크를 지정하여 OpenGL 물체를 그리는 부분입니다.
// OpenCV로 이미지 파일을 읽어들인다.
IplImage *img_bg = cvLoadImage ("sample.jpg");
IplImage *img_gl = cvCreateImage (cvSize(_width, _height), IPL_DEPTH_8U, 3);
IplImage *mask = cvCreateImage (cvSize(_width, _height), IPL_DEPTH_8U, 1);
// OpenGL로 그린 이미지를 읽어온다.
glReadPixels (0, 0, _width, _height, GL_BGR_EXT, GL_UNSIGNED_BYTE, img_gl->imageData );
// OpenGL로 그린 이미지에서 물체가 있는 부분만 흰색 마스크 이미지로 만든다.
cvCvtColor (img_gl, mask, CV_RGB2GRAY);
cvThreshold(mask, mask, 1, 255, CV_THRESH_BINARY);
// OpenCV로 읽은 이미지에다가 마스크를 지정하여 OpenGL 물체가 있는 부분만 복사한다.
cvCopy (img_gl, img_bg, mask);
cvShowImage ("img", img_bg);
cvReleaseImage (&mask);
cvReleaseImage (&img_gl);
cvReleaseImage (&img_bg);