Vmaster974 2010.03.24 15:57 전체공개

OpenCV 1.1pre1 highgui(cvcam)와 MFC를 이용한 카메라 연결

일단 시작하기 전에 이 글은 MFC의 다이얼로그의 Picture Control로 OpenCV를 이용해서 캠 영상을 뿌리기 위한 방법을 알려주는 글입니다.^^v 쉽게 말해서~ 초보용입니다!!
OpenCV의 설치는 했으니 이제 캠과 컴퓨터를 연결해주는 아주 생각만 해도 어렵고 복잡해 보이는 일을 처리해야된다. 하지만 이런 작업들도 OpenCV 라이브러리에 다 들어있다고 하니 cvcam , 이름만 들어도 두근두근 거리게 멋지군!
나도 중간에 안 사실이지만 OpenCV 1.1부터는 cvcam이 사라지고 highgui 속에 포함된다!
다시 말해서 cvcam.lib 는 더이상 없고 함수명도 조금 달라졌다.
1. MFC 프로젝트의 생성
학교에서 지원해주는 Visual Studio 2008(VS는 너무 비싸다, 지원해주는걸 써야지^^;)을 이용해서 간단한 MFC 프로젝트를 생성한다. 그리고 프로젝트 속성에서 추가 라이브러리로
cv.lib cxcore.lib highgui.lib
을 추가한다.
2. stdafx.h 파일 수정
view plaincopy to clipboardprint?
#include<cv.h>// OpenCV 라이브러리
#include<cxcore.h>
#include<highgui.h>
기본적으로 OpenCV를 위한 필요한 헤더 파일을 추가한다.
3. UI의 제작
.rc 파일을 수정하여 자신이 사용할 다이얼로그의 디자인을 구성한다.
4. MediaGestureDlg.h 헤더파일 수정
view plaincopy to clipboardprint?
// For using OpenCV Camera
CWinThread *m_thread;
bool
m_flagThread;
bool
m_cameraState;
CListBox *m_msgLog;
CWnd *m_pCameraWnd;
// OpenCV 카메라 영상처리 쓰레드
void OpenCamera(void);
void OnThreadStart(void);
void OnThreadStop(void);
BOOL
DestroyWindow(void);
위의 멤버변수 및 함수를 추가하여준다. 위의 변수들은 m_thread 는 OpenCV를 이용해서 실시간으로 캠으로부터 이미지를 캡쳐해내기 위한 변수이고 m_msgLog 는 로그용, m_pCameraWnd는 픽처컨트롤용 핸들이다.
위에 것이 이해가 안된다면 MFC 공부하러 고고씽!!
5. MediaGestureDlg.cpp 파일 수정
BOOL CMediaGestureDlg::OnInitDialog() 속에 기본적으로 핸들값과 기본설정을 한다.
view plaincopy to clipboardprint?
UINT
ManageThread(void* pParam)
{
while(pDlg->m_flagThread)
{
pDlg->OpenCamera();
}
return 0; // 쓰레드 내부에서 종료 시키면 더이상 움직이지 않음
}
void CMediaGestureDlg::OnThreadStart()
{
if(!m_flagThread) {
m_flagThread = true;
m_thread = AfxBeginThread(ManageThread, this, THREAD_PRIORITY_NORMAL);
m_thread->m_bAutoDelete = true;
}
}
void CMediaGestureDlg::OnThreadStop()
{
if(m_flagThread) {
m_cameraState = false;
}
}
위의 소스는 쓰레드의 생성과 중지이기 때문에 쓰레드 관련해서 조금만 공부하면 쉽게 이해가 될 것이기 때문에 또 간단하게 넘어가고 제일 중요한 OpenCamera() 함수이다. ManageThread에도 존재하고 있는데 여기서 무한루프를 돌기 때문제 짧고 건조하게 짜주는게 좋지 않을까?
하지만 영상처리! 조금씩 쓰다보면 복잡해진다. 헛소리 그만하고 OpenCamera는 다음과 같이 작성한다
view plaincopy to clipboardprint?
// OpenCV를 이용해서 카메라 영상 불러오기
void CMediaGestureDlg::OpenCamera(void)
{
if(m_flagThread) {
m_cameraState = true; // 캠 켜짐, 쓰레드 중복 실행 방지
IplImage *image = 0; // IplImage 구조체에 그림파일을 저장
CvvImage cvImage;
CRect rect; // 그려진 픽쳐컨트롤의 크기
CvCapture *capture = cvCreateCameraCapture(0);
if(capture) {
AddLog("카메라와의 연결에 성공하였습니다");
m_pCameraWnd->GetClientRect(&rect);
while(m_cameraState) {
cvGrabFrame(capture);
image = cvRetrieveFrame(capture);
cvImage.CopyOf(image, 1);
CClientDC dc(m_pCameraWnd);
cvImage.Show(m_pCameraWnd->GetDC()->GetSafeHdc(), 0, 0, rect.right, rect.bottom);
}
cvReleaseCapture(&capture);
m_cameraState = false;
AddLog("카메라와의 연결을 해제하였습니다");
}
else {
AddLog("에러: 카메라와의 연결에 실패했습니다");
}
m_flagThread = false;
}
}
위의 소스에서 AddLog()는 개인적으로 필요해서 사용하는 함수이기 때문에 무시해도 된다. 기본적인 내용은 OpenCV의 내용과 동일하기 때문에 따로 설명할 것은 없다.
다음으로 소스의 가장 위쪽에 부모 파라미터 포인터 자식포인터를 위해서 아래와 같이 define문을 선언한다.
view plaincopy to clipboardprint?
#define pDlg ((CMediaGestureDlg*)pParam) // 부모 파라미터 포인터 자식포인터 위해
그리고 마지막으로 다이얼로그가 종료될 때 쓰레드도 함께 종료시킬 수 있도록 DestoryWindow를 재정의한다.
view plaincopy to clipboardprint?
BOOL
CMediaGestureDlg::DestroyWindow()
{
if(m_thread) {
OnThreadStop(); // 스레드 종료 후 종료
WaitForSingleObject(m_thread->m_hThread, 1000);
}
return CDialog::DestroyWindow();
}
이렇게만 하면 아래처럼 정상적으로 프로그램이 작동하게 된다. 참 쉽죠잉~!
하지만, 이제부터 본격적인 영상처리의 입문인게요!! 푸하하하!!!
그리고 정말 마지막으로 허접한 위의 소스를 다운 받고 싶은 분은 아래의 링크를 눌러주세요!!
MediaGesture.zip
위의 소스는 OpenCV설치하기 에 적힌 것처럼 OpenCV를 사용하기 위한 설정을 마쳤다면 컴파일 하였을 경우 바로 실행될 것이다. 참고로 Visual Studio 2008로 제작하였다.

0

0

댓글0

    댓글 더보기

    삭제 하시겠습니까? 취소 삭제

    로그인 하시겠습니까? 확인 취소

    댓글을 삭제 하시겠습니까? 확인 취소