Cfile23.uf .123F4B5A4D28B08E122350

RGB 컬러 공간 분리 – 메뉴 기반 구현

이번에는 본격적으로 OpenCV를 사용하여 영상처리를 해 보겠습니다. 그 첫 단계로 메뉴기반 정지영상 처리를 해 볼 것이며, cvSplit함수를 사용하여 RGB 컬러공간을 분리하는 예제를 구현해 보겠습니다.

 

먼저 OpenCV 2.1 C API Reference에서 cvSplit함수를 찾아보면 다음과 같습니다.

Cfile23.uf .123F4B5A4D28B08E122350

cvSplit함수는 다중 채널(Multi-channel)배열을 여러 개의 단일 채널(Single-channel) 배열로 분할하거나, 배열에서 단일 채널을 추출 할 수 있음을 알 수 있습니다.

또한, 입력이 IplImage인 경우에는 cvCopy함수를 사용해서도 같은 결과를 얻을 수 있음을 알 수 있습니다.

 

이미 “영상처리 프로그래밍 by Visual C++”에서 해 본 것처럼 별도의 Class를 만들고 이를 호출하는 방식으로 예제를 구현해 보겠습니다.

 

먼저 해당 기능을 구현할 Class를 만듭니다. 저는 CDeiosColor라고 하겠습니다.

MFC를 공부할 때 헝가리언 표기법(Hungarian notation)을 알아둔다면 많은 도움이 됩니다. MS가 .Net에서 헝가리언 표기법을 포기했다고는 하지만 많은 이름들이 헝가리언 표기법을 근사적으로 따릅니다. 헝가리언 표기법을 반드시 따를 필요는 없지만 대략적으로 봐 둔다면 MFC프로그래밍 뿐만 아니라 각종 라이브러리 사용 시에 많은 도움이 됩니다. 자신만의 코딩 스타일을 만들어서 일관적으로 사용한다면 과거에 만들었던 코드를 분석하거나 디버깅 할 때에 많은 도움을 받게 될 것입니다.

참고로 Class 이름(DeiosColor) 앞의 C는 Class임을 알려주는 MS의 코딩 스타일입니다.

클래스 뷰에서 마우스 오른쪽 버튼을 클릭하고, [추가] → [클래스]를 선택하여 클래스 추가 마법사를 실행합니다.

Cfile26.uf .1758F74E4D28B08E0D5A80

 

[C++ 클래스]를 선택하여 일반 Class를 만든 후 클래스 이름을 지정해 주고 [마침]을 클릭합니다.

Cfile24.uf .162D77494D28B08F15FAF9

 

다음으로 멤버 함수를 추가하겠습니다. 멤버 함수는 DSplitRGB이며 함수 원형은 다음과 같습니다.

void DSplitRGB(IplImage *color_image, IplImage **red, IplImage **green, IplImage **blue)

헤더 파일(DeiosColor.h)에 cv.h를 include 한 후, 소스 파일(DeiosColor.cpp)에 다음과 같이 코딩합니다.

void CDeiosColor::DSplitRGB(IplImage * color_image, IplImage ** red, IplImage ** green, IplImage ** blue)

{

        *red = cvCreateImage(cvGetSize(color_image), IPL_DEPTH_8U,1);

        *green = cvCreateImage(cvGetSize(color_image), IPL_DEPTH_8U,1);

        *blue = cvCreateImage(cvGetSize(color_image), IPL_DEPTH_8U,1);

 

        cvSplit(color_image, *red, *green, *blue, NULL);

}

이번에는 새로운 메뉴를 등록해 보겠습니다. MFC 리소스 뷰의 메뉴 항목을 보면 다음과 같은 4개의 리소스가 보입니다.

Cfile10.uf .13594C4E4D28B08F0D62E7

 

이 중 IDR_MAINFRAME은 문서가 하나도 생성되지 않은 시점의 메뉴를, IDR_MFC_OpenCVTYPE은 한 개 이상의 문서가 생성된 시점의 메뉴를, IDR_POPUP_EDIT은 팝업 메뉴를 의미합니다. 우리는 한 개의 문서(사진)을 필요로 하기 때문에 IDR_MFC_OpenCVTYPE리소스를 편집해야 합니다.

다음과 같은 모양으로 메뉴를 편집하고 다음과 같은 속성을 줍니다.

Cfile2.uf .166F5A4D4D28B08F105B98

Cfile4.uf .1376D54C4D28B09011A757

이번에는 Split RGB메뉴를 클릭했을 때 발생할 이벤트를 처리하는 이벤트 처리기를 등록해 보겠습니다.

[Ctrl + Shift + X]키를 누르면 [Class Wizard]가 열립니다.

Cfile25.uf .196F7C4D4D28B090108BEF

 

“DeiosColor.h”파일을 include한 후 다음과 같이 코딩합니다.

void CMFC_OpenCVView::OnColorSplitRgb()

{

        // TODO: 여기에 명령 처리기 코드를 추가합니다.

        CMFC_OpenCVDoc* pDoc = GetDocument();  

        ASSERT_VALID(pDoc);  

 

        IplImage *color_image = pDoc->m_CvvImage.GetImage();  

 

        if( color_image->nChannels != 3 ){  

            AfxMessageBox( TEXT("컬러 영상이 아닙니다."), MB_ICONSTOP );  

            return;  

        }

 

        IplImage *red, *green, *blue;  

           

        CDeiosColor cColor;  

        cColor.DSplitRGB( color_image, &red, &green, &blue );  

 

        pDoc->CopyClipBoard( red );

        ((CMFC_OpenCVApp *)AfxGetApp())->OnEditPaste();

        CMFC_OpenCVDoc *pDoc1 = (CMFC_OpenCVDoc *)((CMDIFrameWnd*)AfxGetMainWnd())->GetActiveFrame()->GetActiveDocument();  

        pDoc1->SetTitle(TEXT("[SplitRGB()] 변환 결과 - 빨강 채널"));  

 

        pDoc->CopyClipBoard( green );  

        ((CMFC_OpenCVApp *)AfxGetApp())->OnEditPaste();

        CMFC_OpenCVDoc *pDoc2 = (CMFC_OpenCVDoc *)((CMDIFrameWnd*)AfxGetMainWnd())->GetActiveFrame()->GetActiveDocument();  

        pDoc2->SetTitle(TEXT("[SplitRGB()] 변환 결과 - 녹색 채널"));  

 

        pDoc->CopyClipBoard( blue );  

        ((CMFC_OpenCVApp *)AfxGetApp())->OnEditPaste();

        CMFC_OpenCVDoc *pDoc3 = (CMFC_OpenCVDoc *)((CMDIFrameWnd*)AfxGetMainWnd())->GetActiveFrame()->GetActiveDocument();  

        pDoc3->SetTitle(TEXT("[SplitRGB()] 변환 결과 - 파랑 채널"));  

 

        cvReleaseImage( &red );  

        cvReleaseImage( &green );  

        cvReleaseImage( &blue );  

 

        Invalidate( FALSE );  

}

마지막으로 MFC_OpenCV.h에서 OnEditPaste를 public으로 바꿔줍니다.

Cfile9.uf .116EC14D4D28B0911BC278

 

Cfile25.uf .19405A574D28B09119CFCE

Reference
정성환외 1명/컴퓨터 비전 실무 프로그래밍/홍릉과학출판사/2007/274p~287p
최호성/Visual C++ 2008 MFC 윈도우 프로그래밍/프리렉/2009/669p~674p
OpenCV 2.1.0 The Reference Manual/127p

 

cfile10.uf.123821514D28B1571795C9.pdfcfile7.uf.184156574D28B1ED16BFD9.zip

Similar Posts

  • Cam 영상 출력해보기

    지금까지 VS2010과 OpenCV 2.1라이브러리를 이용한 MFC 프로그래밍 기초에 대해서 알아봤습니다. 우리가 하려고 하는 것이 동영상 처리이므로 이번 시간에는 Cam으로부터 영상을 받아와서 출력하는 방법에 대해서 알아보겠습니다. 먼저 새 프로젝트를 Win32 콘솔 응용 프로그램 형식으로 만들어 줍니다.   OpenCV 2.1 라이브러리를 사용하기 위한 각종 세팅은 당연히 해주셔야 겠죠? 자세한 내용은“Visual Studio 2010에서 OpenCV MFC 프로젝트 만들기(http://deios.kr/400)”를 참고하세요….

  • 모덜리스(Modeless) Dialog로 변환하기

    이전 시간에 만들었던 모달(Modal) Dialog를 모덜리스(Modeless) Dialog로 변환해 보겠습니다. Modal Dialog는 Dialog가 실행되는 동안 다른 작업을 하지 못하고, Modeless Dialog는 프로그램 실행 흐름을 방해하지 않는다는 것 정도는 알고 계시죠? 자 그럼 이전 시간 “MFC – Cam 영상 출력해보기(http://deios.kr/420)”에 만들었던 View Dialog를 멋지게 바꿔 보겠습니다.   OnCamView함수를 다음과 같이 수정합니다. void CMFC_OpenCVApp::OnCamView() {       // TODO: 여기에 명령…

  • Drag and Drop 지원하기

    이번 시간에는 드래그 앤 드롭(Drag & Drop) 기능을 구현해 보도록 하겠습니다. App Class의 InitInstance함수에 다음과 같은 코드를 추가하면 끝~! pMainFrame->DragAcceptFiles();   cfile8.uf.163148404D261B97190741.pdfcfile10.uf.133139404D261B9716AF4E.zip 관련된 글: Visual Studio 2010에서 OpenCV MFC 프로젝트 만들기 OpenCV 파일 저장기능 구현 OpenCV 파일 저장기능 구현2 RGB 컬러 공간 분리 – 메뉴 기반 구현2

  • |

    TCP 폭주(혼잡)제어

    TCP의 폭주제어에서 예약방식을 못 쓰고 피드백 기반 방식을 사용하여야 하는 이유를 설명하시오. 예약 방식의 경우 데이터 전송 중 경로상의 라우터에서 폭주 혹은 에러가 발생했을 경우 송신자는 계속 데이터를 보내게 되어 혼잡이 가중된다. 이를 해결하기 위해 피드백 방식을 사용한다.송신자는 약간의 데이터만 전송하여 도착 여부를 확인 후 점점 전송량을 늘려간다. 이처럼 네트워크의 상태에 따라 송신측에서 전송량을 조절하여야 한다….

  • AcroEdit에서 C/C++ Compile 하기…

    이제 슬슬 공부나 해볼까하고 마음먹던중;;; 그냥 갑자기 C를 하고 싶어졌습니다… 이제까지 하려고 하려고 해도… 귀찮아서 접어두었던 C 책 한권을 꺼내서;;; 첫장을 펼처보니 “Turbo C++”를 설치하라는 겁니다… 전 착한 학생이기 때문에(~ㅋ) 하라는데로 설치했죠;;; 설치하고 보니 이게 왼걸;;; 구석기시대에서나 볼수있는 인터페이스;;; ㄷㄷ;;; 그래서 부대안에 있을때 사용했던 AcroEdit과 연결하기로 마음먹었습니다… 열심히 컴파일러를 찾아 해매였는데…;;; 이게 왠걸;;; 도처히 못찾겠습니다.;;;…

One Comment

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다