프로그래밍/영상처리

02. 영상처리용 라이브러리 기본내용

산을좋아한라쯔 2017. 10. 8. 13:02
반응형

"열혈강의 - 영상처리 프로그래밍"에서 작성된 영상처리용 기본 라이브러리에서, 꼭 알아야할 사항만 요약해 봤다.


1. CMyImage 클래스

영상 이미지는 CMyImage클래스로 표현된다. 

CMyImage에서 실제 이미지 데이터를 표현할 변수형은 Byte가 대표적이지만, 다른 변수형도 사용할 수 있도록 template을 사용하고 있어서, int나 float형으로 이미지 데이터 처리도 가능하다. 그러나, 대부분은 Byte를 사용하는게 변하기에 다음과 같은 형태로 사용.

  CByteImage image = ...


영상에 대한 기본정보를 가지고 있는 CMyImage클래스의 변수는 다음과 같다.


protected:

         int               m_nChannels;      // 채널 수, if 1:흑백  3:RGB

         int               m_nHeight;        // 세로 픽셀 수

         int               m_nWidth;         // 가로 픽셀 수

         int               m_nWStep;         // 행당 데이터 원소 수

         T*                m_pImageData;     // 픽셀 배열 포인터


픽셀에 대한 정보는 m_pImageData에서 1차원 배열로 저장됨에 유의.

또한, 한 행의 원소수는 4의 배수가 되도록 해준다. (한 행이 22개 픽셀이면, 끄트머리에 2개의 의미없는 공간을 더 둔다.)

따라서, 한 행당 데이터 원소수는,

 m_nWStep = ((m_nWidth*m_nChannels*sizeof(T)+3)&~3)/sizeof(T);

즉, 가로픽셀 수에(m_nWidth)에, 한 픽셀당 채널 수(m_nChannels)를 곱하고, 데이터 표현을 위한 변수(T)의 크기를 곱하고서는, 이 값을 4의 배수가 되도록 3을 더하고 3으로 나눠 준다. 

 어떤 수 A를 4의 배수로 만드는 방법

1)A를, A보다 크거나 같은 가장 가까운 4의 배수 B보다 크고 (B+1)보다 작게 만든다. : A+3

2)(A+3)에 대해, 제일 작은 두 비트를 00으로 만든다. 즉, (~3 = 1111 1100)과 AND 연산 시킨다. : (A+3)&(~3)

  ==> 4의 배수 정수의 경우, 끝 두 비트가 항상 00인 성질을 이용한 것임 

ex) A=10=1010b --> A=A+3=13=1101 --> A&(~3) = 1101 & (1100) = 1100 = 12


m_pImageData가 1차원배열이기에, 이미지에서 행이 행이 r이고, 열이 c인 위치에 해당하는 값을 가져오려면, 해당 위치를 계산으로 알아내야한다. 즉,

T*  GetPtr(int r=0, int c=0)       const { return m_pImageData + r*m_nWStep + c; }


따라서, 이미지의 전체 픽셀을 방문하고자 한다면 다음과 같이하면 된다.

         int nWidth = image.GetWidth();

         int nHeight = image.GetHeight();  

         for (int r = 0; r < nHeight; r++) {

                  BYTE* p = image.GetPtr(r);

                  for (int c = 0; c < nWidth; c++) {

                           p[c] = p[c] + 10;

                  }

         }


2. 영상파일 읽어서 CMyImage클래스 만들기

LoadImageFromFileDialog.h 파일을 include하고, 다음과 같이 하면 된다.

         CByteImage image = LoadImageFromDialog();


3. 영상을 화면에 출력하기, 파일로 저장하기

새로운 frame을 만들고 거기에 영상출력하는 것은 ShowImage함수를 사용해서 간단히 가능

저장하는 것은 CMyImage클래스의 SaveImage함수 사용


#include "imageSrc\ImageFrameWndManager.h"

CByteImage image = LoadImageFromDialog(); //LoadImageFromFileDialog.h

        

if (image.IsEmpty()) return;

ShowImage(image, "Hello~"); //ImageFrameWndManager.h

image.SaveImage("hello.bmp");

 



-끝- 

반응형