상세 컨텐츠

본문 제목

CAM을 활용한 영상처리 프로그램

프로그래밍 관련

by AlrepondTech 2016. 12. 9. 12:18

본문

반응형
728x170



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


출처: http://snakecharm.tistory.com/category/Win32%20Api


CAM을 활용한 영상처리 프로그램

HDC hdc;
HWND hWndMain;
HWND hVfw;
BITMAPINFO Bm;
LRESULT CALLBACK FramInfo(HWND, LPVIDEOHDR);

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
  static PAINTSTRUCT ps;

  switch(iMessage)
  {
  case WM_CREATE:
    hWndMain = hWnd;
    hVfw = capCreateCaptureWindow(TEXT("동영상 캡처"), WS_CHILD|WS_VISIBLE,0,0,400,300,hWnd,0);
    capDriverConnect(hVfw,0);
    capGetVideoFormat(hVfw, &Bm, sizeof(Bm));
    capSetCallbackOnFrame(hVfw, FramInfo);
    capPreviewRate(hVfw, 33);           // 프레임 설정
    capPreview(hVfw, FALSE);            // FrmaInfo 콜백함수 사용하여 출력해주기위해 FALSE
    return 0;

  case WM_DESTROY:
    PostQuitMessage(0);
    return 0;
  }
  return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}

LRESULT CALLBACK FramInfo(HWND hWnd, LPVIDEOHDR lpData)
// 캡쳐된화면을 윈도우창에 뿌려주는 함수
  static int iCntX;
  static int iCntY;
  static int iJump;
  
  hdc = GetDC(hWndMain);

  StretchDIBits(hdc, 00, Bm.bmiHeader.biWidth, Bm.bmiHeader.biHeight,
          00, Bm.bmiHeader.biWidth, Bm.bmiHeader.biHeight, lpData->lpData,
          &Bm, DIB_RGB_COLORS, SRCCOPY); 

  iJump = 0;
  for(iCntY=0; Bm.bmiHeader.biHeight>iCntY; ++iCntY)
  {  // RGB값을 찾아서 변환해 주는 곳
    for(iCntX=0; Bm.bmiHeader.biWidth>iCntX; ++iCntX, iJump+=3)
    {
      if(lpData->lpData[iJump+2]>230)    // Red
      {
        if(lpData->lpData[iJump+1]>230)    // Green
        {
          if(lpData->lpData[iJump+0]>230)    // Blue
          {
            lpData->lpData[iJump] = 0;    // Blue
            lpData->lpData[iJump+2= 255;  // Red
            lpData->lpData[iJump+1= 0;  // Green
          }
        }
      }
    }
  }

  ReleaseDC(hWndMain, hdc);
  return 0;
}
1. vfw의 기능 

VFW는  실시간 영상 처리를 위한 비디오를 캡처하고 화면을 캡처 
수정하기 위한 프레임 캡처 기능을 제공한다.

또한 Media Control Interface라고 불리는 MCI 장치를 제어해 주는 기능을
통해 비디오 소스의 시닥과 중지를 제어하는 기능이 있다.

VFW의 다양한 기능 
- 이미지 캡처 및 저장(DIB와 같은 비트맵 파일 형식 )
- 클립보드에 이미지와 팔레트 복사 기능
- 비디오 화면 구현을 위한 창을 생성 가능
- 캡처 비율을 조정 가능 
- 실시간 캡처 기능 지원
- 오디오 및 비디오 동적 연결 및 해제 기능 지원
- 저장 기능 (AVI 파일 형식)

2. VFW 비디오 처리를 위한 주요 함수 

비디오 처리를 위해서는 주로 영상 캡처 관련 함수인 CAP*** 형태의 함수를 이용한다
vfw 에서는 AVICap 라이브러리를 통해 실시간 영상 처리를 가능하게 한다 

capCreateCaputreWindow
- 화면 캡처에 사용할 윈도우 생성 
capDriverConnect
- 영상캡처 드라이버와 캡처된 화면을 보여주는 캡처 윈도우와의 연결 시도 
capDriverDisconnect
- 영상 캡처 드라이버와 캡처된 화면을 보여주는 켑처 윈도우와의 연결 해제 
capPreview
- 미리보기 실행 및 중지 설정(CPU자원 미사용)
capOverlay
- 오버레이보드를 통해 바로 화면 출력(CPU자원 미사용)
capPreviewRate
- 프레임을 출력하는 속도조절( 릴리초 단위)
capDlgViedoFormat
- 캡처 윈도우에 출력되는 영상 화면에 대한 크기 및 포맷 설정 
capGetVideoFormat
- 영상 복사를 위해 사용 포맷의 크기를 바이트로 반환 
capGetvideoFormatSize
- 영상 포맷의 크기를 바이트 크기로 반환 
capSetCallbackOnFrame
- 미리보기 모드로 화면을 캡처할 경우 Callback 함수를 사용하여 처리를
   하게 된다. 이때 이 함수를 설정하여 처리할 Callback함수명을 지정하게 된다
   NULL을 지정하면 해제 된다 
capGrabFrameNoStop
- 실시간 출력 중인 영상 프레임 하나를 정지영상으로 캡처한다


capCreateCaptureWindow
- HWND VFWAPI capCreateCaptureWindow( 
   LPCSTR lpszWindowName, // 캡처된 영상을 출력할 윈도우 이름 
   DWORD dwStyle,  // 윈도우 스타일 
   int x,   // 왼쪽 위부분 x좌표 
   int y,   // 왼족 윗부분 y좌표 
   int nWidth,  // 윈도우의 넓이 
   int nHeight,  // 윈도우의 높이 
   HWND nWnd,   // 캡처 윈도우를 포함하는 부모 윈도우 핸들 
   int nID // 캡처 윈도우의 ID값 지정 );

실시간 영상을 처리할 수 있는 윈도우 창을 생성한다 옆의 주석 처럼 각각의
특성을 지정하여 사용하면 된다 
정상적으로 생성이 되면 캡처 윈도우의 핸들 값이 반환이 되고, 그렇지 않을
경우에는 NULL값이 반환이 된다 

capDriverConnect
 BOOL capDriverConnect(
 HWND hwnd,  // 캡처 윈도우의 핸들 
 int iIndex  //캡처 드라이버 넘버 0~9 까지의 값
 );
 캡처 윈도우를 캡처 드라이버에 연결하는 함수이다. 캡처 장치가 정상적으로 연결되면 
 TRUE , 그렇지 않으면 FALSE 값을 반환한다 

capDriverDisconnect
 BOOL capDriverDisconnect(
 HWND hwnd// 캡처 윈도우 핸들 
  );
  캡처 윈도우에 연결된 드라이버를 분리한다 , 성공하면 TRUE , 실패하면 FALSE 반환한다

capPreview
 BOOL capPreview(
 HWND hwnd,  // 캡처 윈도우 핸들 
 BOOL f     // 활성화 비활성화를 결정하는 플래그 (TRUE 이면 활성화)
 );
 프레임을 캡처하고 callback 함수를 이용하여 직접 디스플레이을 하고자 한다면 f플래그를
 비활성화(FALSE) 시킨다. 프리뷰 모드는 CPU자원을 사용한다.

capOverlay
 BOOL capOverlay(
 HWND hwnd,    //캡처 윈도우 핸들 
 BOOL f           // 활성화 비활성화를 결정하는 플래그 (TRUE 이면 활성화
 CPU 자원을 전혀 사용하지 않고 영상을 출력하는 방법이다 . FALSE 가 리턴 될 경우
 오버레이 모드가 사용할 수 있음을 나타낸다.

capPreviewRate
 BOOL capPreviewRate(
 HWND hwnd,     //캡처 윈도우 핸들 
 wMS               // 밀리초(ms)단위로 프레임 캡처 및 디스플레이 
 );
  프레임 재생 속도를 지정한다 . 만약 66을 지정하면 ,0.066초 마다 디스플레이가 된다 
  , 따라서 1초의 경우 
   1000(md) % 66(ms) =15.1515  즉 1초에 15번 디스플레이하게 된다 

capDlgVideoFormat
 BOOL capDlgViedoFormat(
 HWND hwnd     // 캡처 윈도우 핸들 
 );
  사용자가 비디오의 프레임 크기와 이미지 포맷을 결정하게 하는 함수이다 
  CAPDRIVERCAPS의 구조체의 멤버 값이 업데이트 된다. 성공하면 TRUE, 
   실패하면 FALSE 를 리턴한다

capGetVideoFormat 
 DWORD capGetVideoFormat(
 HWND hwnd,       // 캡처 윈도우 핸들 
 LPVOID  psVideoFormat,         //BITMAPINFO 의 구조체 포인터
size wSize       // psVideoFormat가 참조체는 구조체의 크기
 );
 비디오 포맷의 복사본을 얻을 때 사용하고, 비디오 포맷의 크기를 바이트 크기로
  반환한다 

capGetVideoFormatSize
 CWORD capGetVideoFormatSize(
 HWND hwnd     // 캡처 윈도우 핸들
  );
  비디오 포맷의 크기를 바이트 크기로 반환한다 

capSetCallbackOnFrame
 BOOL capSetCallbackFrame(
 HWND hwnd,             // 캡처 윈도우 핸들 
 LPVOID fpProc          // 콜백 함수에 의해 호출되는 함수의 포인터
 );
비디오 프레임이 캡처 되었을 경우 이값을 처리하기 위한 함수명을 설정해주는
매크로 함수로써 일반적으로 아래와 같은 형식의 방법으로 선언되어 사용한다

LRESULT CALLBACK 콜백 함수면 (
 HWND hwnd,          // 캡처 윈도우 핸들 
 LPVIDEOHDR lpVHdr     // VIDEOHDR 구조체에 대한 포인터 
 );
 lpVHdr 구조체의 LPBYTE lpData(데이터 버퍼에 대한 데이터) 멤버를 참조함으로써
 캡처된 이미지 데이터에 접근할 수 있게 된다 

capGrabFarmeNoStop
 capGrabFrameNoStop(
 HWND hwnd   // 캡처 윈도 핸들 
 );
 압축되지 않는 한 프레임 데이터로 프레임 버퍼를 채운다 보통 콜백 함수를 호출하기
 전에 이 함수를 호출하여 이미지를 캡처한 후 , VIDEOHDR 구조체의 lpData멤버를
 참조하여 이미지를 디스플레이 한다 

3. VFW 관련 구조체 

VIDEOHDR 구조체
비디오 헤더 정보를 나타내는 구조체
콜백 함수 내에 사용되는 구조체로써, 멤버 변수 lpData 의 값을 적절하게 넘겨 주기
위해 사용한다 

typedef struct videohdr_tag(
LPBYTE lpData,   // 데이터 버퍼에 대한 포인터 
DWORD dwBufferLength,    // 데이터 버퍼의 길이 
DWORD dwBytesUsed,      // 실제로 사용된 바이트 
DWORD dwTimeCaptured,  //ms단위의 스트림 시작점 
DWORD dwFlag,    //임의의 정의된 플래그 
DWORD_PTR dwReserved[4],     //드리이브를 위한 예약 
} VIdEOHDR, NEAR *PVIDEOHDR , FAR *LPVIDEOHDR;

CAPSTATUS 구조체
캡처 윈도우의 현재 상태를 나타내는 구조체 
비디오 프레임의 크기와 이미지 포맷을 지정하는 대화상자 출력시 활용된다

capDlgVideoFormat 함수 
typedef struct{
UINT uiImageWidth,       // 이미지의 넓이 
UINT uiImageHeight,      // 이미지의 높이 
BOOL fLiveWindow,       //프리뷰모드를 사용하고 있다면 TRUE값을 반환 (flag변수)
BOOL fOverlayWindow,     // 오버레이모드를 사용하고 있다면 TRUE 값을 반환(flag 변수)
BOOL fScale,                  //입력 크기 조정 플래그, 클라이언트에 입력 크기 조정시
                                     // TRUE 값 설정(flag변수)
POINT ptScroll,               // 윈도우 클라이언트 영역 내 좌측 좌표 x, y 의 값
BOOL fUsingDefaultPalette,    // TRUE 이면 디폴드 팔래트를 사용한다(flag 변수)
BOOL fAudioHardware,    // WaveForm-audio 하드웨어가 설치 되어 있다면 TRUE(flag변수)
BOOL fCapFileExists,     // 유효한 캡처 파일이 생성되면 TRUE(flag 변수)
DWORD dwCurrentVideoFrame,   // 가장 최근 스트림 된 캡처 프레임의 개수(드랍된 프레임 포함)
DWORD dwCurrentVideoFramesDropped, // 드랍된 프레임의 갯수
DWORD dwCurrentWaveSamples,     // 현재 스트리밍 캡처의 파형-오디오 샘플을 갯수
DWORD dwCurrentTimeElapsedMS, // 시작한 스트리밍 캡처로 부터의 현재 시간, ms단위
HPALETTE hPalCurrent,                 // 현재 팔래트 핸들 
BOOL fCapturingNow,                    // 캡처 진행 중임을 확인하는 플래그, TRUE 면 진행중 
DWORD dwReturn,                         // 에러시 값을 리턴한다
UINT wNumVideoAllocated,           // 할당된 비디오 버퍼의 갯수 
UINT wNumAudioAllocated,           // 할당된 오디오 버퍼의 갯수 
} CAPSTATUS;


CAPTUREPARMS 구조체 
스트리밍 비디오 캡처를 하는 요소들로 구성이 되어 있다 이구조체는 캡처 비율, 버퍼 수
캡처 종료 방법 등에 영향을 주는 변수들을 설정하거나 값을 복사한다

typedef struct{
DWORD dwRequestMicroSecPerFame,   // 프레임 속도 비율,  66667은 초당 15프레임을 의미
BOOL fMakeUserHitOKToCapture,          // 사용자가 캡처를 시작했음을 대화상자를 뛰어보여주는
                                                         // 플래그
UINT wPercentDropForError,                 // 놓치는 프레임은 %비율로 제한 ( 기본값;10)
BOOL fYield,                                      // 쓰레드를 생성시켜 캡처링(TRUE 의 경우 캡처링 시작)
DWORD dwIndexSize,                         // 캡처 할 수 있는 프레임 혹은 오디오 버퍼의 갯수에 대한 
                                                        // 제한 0~34,952
UINT wChunkGranUlarity,                    // AVI파일의 논리적 블럭 (0:현재 섹터 크기가 알갱이처럼 
                                                        // 사용되고 있음을 가리킨다 
BOOL fUsingDOSMemory,                  // Win32 응용 프로그램에서는 사용하지 않음
UINT wNumVideoRequested,              // 할당된 비디오 버퍼의 최대 갯수 
BOOL fCaptureAudio,                         // 오디오 캡처 여부 (FLASE 이면 캡처 금지 )
UINT wNumAuidoRequested,             // 할당된 오디오 버퍼의 최대 개수 (최대 10)
UINT vKeyAbort,                              // 연속 캡처를 종료에 사용하는 가상 키코드 RegisterHotKey함수를
                                                     // 사용하여 변경 가능하다
                                                     // ESC 키를 누르면 캡처 종료(디폴드값)
BOOL fAbortLeftMouse,                    // 왼쪽 마우스를 눌러도 캡처종료 처리 여부
                                                     // (FALSE=>캡처 종료 불가능하게)
BOOL fAbortRightMouse,                 // 오른쪽 마우스를 눌러도 캡처 종료 처리 여부 
                                                    // (FALSE=>캡처 종료 불가능하게)
BOOL fLimitEndabled,                     //  TRUE 시간 제한 있음 FALSE 시간 제한 없음
UINT wTimeLimit,                          // 시간 제한( 초단위), fLimitEndabled이 TRUE일때만 사용가능
BOOL fMCIContol,                         // MCI 장치 스텝 캡처 플래그 FALSE 이면 MCI장치 이용한
                                                  // 스텝 갬처가 가능 해짐
DWORD dwMCIStartTime,             // 캡처시컨스를 위한 MCI장치의 ms단위 시작
DWORD dwMCIStopTime,            // 캡처시커스를 위한 MCI 장치의 ms단위 중단 
                                                    // (fMCIControl이 FALSE면 무시된)
BOOL fStepCaptureAt2x,              // 이중으로 해상도를 높이는 경우 사용 (TRUE일때 사용,RGB형식에서)
UINT wStepCaptureAverageFrames, // 한프레임을 만들때 프레임이 캡처 되는 횟수 평균치는 5
DWORD dwAudioBufferSize,             // 오디오 버퍼 사이즈
BOOL fDisableWriteCache,              // Win32 에서는 사용 안함 
UINT AVStreamMaster,                   // AVI 파일을 기록할때 오디오 스트림과 비디오 스트림의 
                                                    // 매치를 할것인지 판단하는 변수
} CAPTUREPARMS;

비트맵 인포 구조체 

typedef struct tagBITMAPINFO{
BITMAPINFOHEADER bmiHeader,      // 칼라 포맷에 대한 정보를 담은 구조체 선언
RGBQUAD bmiColors[1],                  // 칼라 테이블의 색상을 지정한다
} BITMAPINFO, *PBITMAPINFO;

typedef struct tagBITMAPINFOHEADER{
DWORD biSize,       // BITMAPINFOHEADER 구조체의 크기 
LONG biWidth,          // 이미지의 가로크기 
LONG biHeight,         // 이미지의 세로 크기 
WORD biPlanes,        // 장치의 플레인 수 91로 설정해야함
WORD biBitCount       // 각픽셀의 비트수 
DWORD biCompression,    // 압축 방법 설정 
DWORD biSizeImage,        // 비트맵 이미지 크기 
LONG biXPelsPerMeter,    // 수평 해상도 
LONG biXPelsPerMeter,    // 수직 해상도
DWORD biClrUsed,           // 사용된 컬러의 수 
DWORD biClrImportant,      // 비트맵 출력에 사용되는 컬러의 수 
}BITMAPINFOHEADER, *PBITMAPINFOHEADER;



-------------------------------------------------------------------------------------------------------------------------------------------------------------





API Win32 영상처리 라이브러리 등록 방법


Win32에서 라이브러리 vfw 로 지원한다. 등록 방법은 다음과 같이 하면 된다.



 위의 그림과 같이 메뉴창에서 Project창에서 Settings로 들어간다 단축키는 Alt+F7



 그러면 위와 같이 새창이 뜨는데 탭메뉴에서 Link를 찾아 들어간다. Link탭에 보면 Object/library modules라는 곳이 있는 이곳에 vfw32.lib를 등록 시켜주고  OK눌러주면 된다. 이 방법으로 자기가 셋팅해놓은 컴퓨터에서는 사용이되지만 다른 컴퓨터에서는 셋팅이 안되어 있기때문에 다시 똑같은 작업을 해주어야하는 번거로움이 있다. 이 해결법은 이방법말고 다른 방법이 있는데 다음과 같다.



 위와 같이 소스에 #pragma comment(lib,"vfw32.lib") 이란 명령어를 추가해주면 처음과 같은 방법으로 하지 않아도 라이브러리를 가져올수가 있다. 그리고 컴퓨터를 옮기거나 프로그램 삭제했다가 다시 설치해도 처음 방법처럼 다시 셋팅해줄 필요가 없다.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

반응형
그리드형


관련글 더보기

댓글 영역