초급] OpenCV 초보를 위한 강좌 - 2편 : 카메라 입력받기

이번 강좌에서는 OpenCV 를 이용하여 간단하게 카메라 영상을 입력받아 IplImage 형 구조체에 넣고 출력 윈도우의크기를 조절해서 화면에 보여주는 작업을 할 것입니다. 1편을 통하여 기본적인 셋팅 방법은 습득 하셨을테니 바로 아래와 같은소스코드를 작성한 후 컴파일 해 봅시다.

 
- 소스 코드(압축 파일 첨부)
 
#include <cv.h>
#include <highgui.h>

void main()
{
    IplImage* image = 0;
    CvCapture* capture = cvCaptureFromCAM(0);
    cvNamedWindow( "T9-camera", 0 );

    cvResizeWindow( "T9-camera", 320, 240 );

       
    while(1) {
        cvGrabFrame( capture );
        image = cvRetrieveFrame( capture );

        cvShowImage( "T9-camera", image );
 
        if( cvWaitKey(10) >= 0 )
            break;
    }

    cvReleaseCapture( &capture );
    cvDestroyWindow( "T9-camera" );
}

 
- 소스 설명

일 단 OpenCV 를 사용하기 위하여 영상처리 관련 라이브러리를 사용하기 위해 <cv.h> 를 include하고 영상을 캡쳐 받고 윈도우로 보여주기 위해 <highgui.h> 를 include 하지만 사실 카메라 영상만 입력받아 화면에 보여줄 것이라면 <highgui.h> 만 include 해도 됩니다.

  #include <cv.h>         // 영상 처리를 위한 header
  #include <highgui.h> 
// 카메라로 영상을 입력받거나 이미지를 읽어들이고 화면에 보여주기 위한 header

 다음은 IplImage 구조체로 image라는 포인터를 생성하여 앞으로 이 것으로 이미지를 받고 처리하게 됩니다. IplImage 의 구조체는 이미지에 관련된 다양한정보를 가지고 있으며 char 형 imageData 를 가지고서 이미지에 직접적인 접근을 할 수 도 있습니다.

 
  IplImage* image = 0;

cvCaptureCAM() 함수를 이용 0번째 연결된 카메라로부터 컨트롤을 얻어 옵니다. 숫자를 넣는 부분에 카메라의 인덱스 번호를 넣으면 현재 2 대 까지 연결이가능하며 이렇게 연결된 capture 는 끝나기 전에 cvReleaseCapture() 함수로 release 해 주어야 합니다.

  CvCapture* capture = cvCaptureFromCAM(0);  // 0 번째 연결된 카메라로부터 컨트롤을 얻어 옵니다.

 cvNamedWindow() 함수는 "T9-camera" 라는 타이틀의 윈도우를 생성합니다. 두번째 인자 값은 고정된 윈도우(0)를 생성 하거나 보여질 이미지의 크기에 맞게 자동 조절 윈도우(1)를 생성 할 수 있습니다. 두 번째 인자를 0 으로 하고 아래 문장을 추가하면 윈도우 크기를 자유롭게 조절 할 수 있습니다. 이것은 입력 소스를 조절하는 것이아니라 출력 창의 크기를 조절 하는 것이므로 화면의 크기를 키울 경우 사각 픽셀이 보이는 현상이 나타납니다.

  cvNamedWindow( "T9-camera", 0 );            // T9-camera 라는 이름의 윈도우를 생성, 0 은 고정된 윈도우를 생성
  cvResizeWindow( "T9-camera", 320, 240 );  // T9-camera 라는 이름의 윈도우 크기를 조절 width = 320, height = 240

 그리고카메라로 부터 매 프레임을 받아오기 위해서 while(1) 문으로 무한 loop 을 돌립니다. 이 무한 loop 는 if(cvWaitKey(10) >= 0 ) 문장을 통해 'ESC' 키가 눌려지면 종료하게 되고 종료되지 않는다면 다음과같은 작업을 반복하게 됩니다. cvGrabFrame( capture ) 함수는 카메라로 부터 입력된 영상의 한 프레임을 잡고,cvRetrieveFrame( capture ) 함수는 잡은 프레임으로부터 이미지를 얻어 냅니다. 이 두 함수는 함께 쓰이며카메라로부터 영상을 받아 이미지에 넣는 과정이라고 보시면 됩니다. 다음으로 cvShowImage( "T9-camera",image ) 함수는 image 를 "T9-camera" 라는 타이틀의 윈도우에 뿌려주게 되는데 해당 타이틀의 윈도우는cvNamedWindow() 함수로 이전에 미리 만들어 두어야 합니다.

  while(1) {
      cvGrabFrame( capture );                    // 카메라로부터 한 프레임을 잡습니다.

      image = cvRetrieveFrame( capture );    // 잡은 프레임으로부터 IplImage 형 구조를 리턴 받아 image 에 넣습니다.

      cvShowImage( "T9-camera", image );  // "T9-camera" 윈도우에 image 를 보여줍니다.
 

      if( cvWaitKey(10) >= 0 )
          break;
  }

 

마지막으로 capture 를 release 하여 카메라와의 연결을 종료하고 윈도우를 소멸시키면 프로그램은 안정적으로 종료됩니다.

  cvReleaseCapture( &capture );
  cvDestroyWindow( "T9-camera" );

다음은 cvNamedWindow() 함수와 cvResizeWindow() 함수를 이용하여 윈도우 창의 크기를 변화 시켜 출력한 결과 화면입니다.

>> 소스코드 결과 화면

     cvNamedWindow( "T9-camera", 0 ) 함수에서 두번째 인자가 '0' 이고
     cvResizeWindow( "T9-camera", 320, 240 ) 함수를 추가 한 경우

>> cvNamedWindow( "T9-camera", 0 ) 함수에서 두번째 인자가 '0' 일 경우

>> cvNamedWindow( "T9-camera", 1 ) 함수에서 두번째 인자가 '1' 일 경우


- 주요 함수

A.윈도우 관련

  cvNamedWindow( "T9-camera", 0 );
  cvShowImage( "T9-camera", image );
  cvDestroyWindow( "T9-camera" );

 
B.카메라 영상 캡쳐 관련

  CvCapture* capture = cvCaptureFromCAM(0);
  cvGrabFrame( capture );
  image = cvRetrieveFrame( capture );

  cvReleaseCapture( &capture );

Copyrights (c) 2005 OpenCV.co.kr. All rights reserved.

Media System Lab., Yonsei University
by Dong-Chul Kim, e-mail: opencv at opencv.co.kr

- T9T9.com

OpenCV 초보를 위한 강좌 1편

OpenCV 는 인텔에서 만든 강력한 영상처리 라이브러리입니다.

강력한 기능과 성능에도 불구하고 3D 의 오픈소스라이브러리인 OpenGL 처럼 알려지지도 않고,

활발하게 개발되지도 않고, 자주 쓰이지도 않아 안타까운 심정입니다.

더욱이 국내에는 아직 활성화된 커뮤니티가 없어 자료를 구하기도 어려운 실정입니다.

그리하여 본인이 자료를 수집하고 공부하는 과정에서부딪친 문제점들의 해결방법들과

습득한 지식들을 강좌를 통해 풀어나가 보려고 합니다.

강좌는 다음과 같은 목차로 진행될 예정이며예제 위주와 간결한 문체를 사용하여 정리 하도록 하겠습니다.

개발 환경은 별도로 거론하지 않는다면 다음과 같습니다.


- Windows XP Platform

- Visual C++ 6.0

- OpenCV beta 5.0a



- 목 차 -

1. OpenCV 란 무엇인가?

2. OpenCV 설치하기

3. OpenCV 셋팅

 

- 본 문 -

1. OpenCV 란 무엇인가?

- OpenCV(Open Source Computer Vision) 인텔에서 만든 강력한 영상처리 라이브러리입니다.

- 기초 영상처리서부터 고급 수준의 영상처리 까지 상당한 량의 알고리즘들이 함수로 구현되어 있습니다.

- Binarization, Noise, Motion Detect, Edge Detect, Pattern Recognition, Hidden Markov Model 등등

- 오픈소스로서 스펙만 맞추면 자신의 알고리즘도 라이브러리에 등록 시킬 수 있습니다.

- 인텔의 OpenCV 사이트 http://www.intel.com/technology/computing/opencv/index.htm



2. OpenCV 설치하기

- OS Platform 에 맞게 OpenCV 라이브러리 다운받아 설치합니다.

- Linux 와 Windows 용이 있고 Mac OS 에서도 돌아간다고 합니다.

- 최신 OpenCV 가 Release 되는 곳

    http://sourceforge.net/projects/opencvlibrary


- 다운받기 OpenCV beta 5.0a for Window platform

    http://nchc.dl.sourceforge.net/sourceforge/opencvlibrary/OpenCV_b5a.exe

    http://keihanna.dl.sourceforge.net/sourceforge/opencvlibrary/OpenCV_b5a.exe



3. OpenCV 셋팅

기본적을 OpenCV 를 돌아가게 하려면 크게 4가지 작업을 해주어야 합니다.


1. 첫번째, Visual Studio 셋팅에서 디렉토리 추가하기

  개발 환경에서 컴파일러가 헤더 및 라이브러리 파일들을 찾을 수 있도록 한번만 셋팅해 주면 됩니다.


  - Include files

    C:\PROGRAM FILES\OPENCV\CXCORE\INCLUDE
    C:\PROGRAM FILES\OPENCV\CV\INCLUDE
    C:\PROGRAM FILES\OPENCV\OTHERLIBS\HIGHGUI
    C:\PROGRAM FILES\OPENCV\OTHERLIBS\CVCAM\INCLUDE


  - Library files

    C:\PROGRAM FILES\OPENCV\LIB


2. 두번째, 프로젝트에 Link 하기

  라이브러리 파일들을 링크 해 줍니다.

  원칙적으로는 소스 코드에 쓰인 라이브러리만 링크 해주면 되지만 일일이 어디에 속해 있는 함수인지 알기가 번거로움으로 일반적으로는 앞에 세가지를 기본적으로 링크하면 됩니다.

  cxcore.lib, cv.lib, highgui.lib, cvcam.lib


3. 세번째, 소스파일에 header 파일 include 하기

  #include <cv.h>

  #include <cxcore.h>

  #include <highgui.h>


4. 네번째, dll 파일 복사하기

  C:\Program Files\OpenCV\bin 폴더에서 다음과 같은 파일들을 Workspace 파일이 있는 폴더에 복사 합니다.

  만약에 라이브러리를 사용하지 않았을 경우에는 필요한 파일만 복사하면 됩니다.

    cv097.dll, cxcore097.dll, cvcam097.dll, highgui097.dll

< IplImage >

- OpenCV의 이미지 구조체


// 선언하기 (1차포인터 선언)

 IplImage *pSample = NULL;


// 이미지 로드하기

// cvLoadImage 함수를 이용해서 로드

// 두번째 인자는 양수값이면 강제로 3칼라(RGV), 0이면 강제로 흑백, 음수값이면 이미지 원래의 칼라를 따름

 pSample = cvLoadImage("sample.jpg", 1);
 

// 이미지 세이브하기

// 두번째 인자에 IplImage의 형태는 2차포인터이므로 &pSample 임

int cvSaveImage( char*형 파일이름, &pSample );

 

// 이미지 복사

// 빈 포인터 하나 만들고

IplImage *pCopySample = NULL;

 
//  같은 싸이즈로 빈 이미지를 하나 만들고

pCopySample = cvCreateImage( cvSize(pSample->width, pSample->height) ,IPL_DEPTH_8U, pSample->nChannels );

 

// OPENCV 소스에 있던 내용인데요 origin이 IPL_ORIGIN_TL에 따라 그냥 복사.. 혹은 Flip 시킴

if( image->origin == IPL_ORIGIN_TL )

{
     cvCopy( image, frame_copy, 0 );

}
else
{
     cvFlip( image, frame_copy, 0 );

}

// 복사후 필요없으면 pSample, pCopySample 모두 해지할것...

 

// 닫기

// 릴리즈함수

ReleaseImage( &pSample );

+ Recent posts