OpenCV의 이미지 처리 방법과 Mat 클래스

C++에서 시작하는 OpenCV에 이어서, 오늘은 OpenCV에서 사용하는 기본 클래스들에 대해 알아보겠습니다.


OpenCV는 우리가 컴퓨터에서 영상처리를 위해 사용하는 라이브러리입니다. 실제로 포토샵 등에서 사용하는 GRAYSCALE효과 등은 이런 OpenCV와 매우 흡사하며 이를 우리가 무료로 직접 프로그래밍할 수 있도록 제공하는 라이브러리가 바로 OpenCV였다는 것을 지난 포스트에서 알 수 있었습니다.



Image Processing

이미지 처리는 어떤 방식으로 이루어질까요? 그 전에 컴퓨터에서는 우리가 주는 이미지를 어떻게 처리하는지부터 한 번 알아보도록 하겠습니다.


위에 어떤 한 사진이 있습니다. 우리에게는 그냥 그저 이미지일 뿐이지만, 우리는 이를 디지털화된 이미지라고 표현합니다. 디지털화된 이미지란, Pixel이라 부르는 점들이 모여서 형상을 만든 것을 말합니다. 실제 이미지는 이 점들의 모임으로 컴퓨터는 이 점들의 값들을 통해 이미지의 모습을 바꾸어 표시하는 등 여러 가지 표현을 할 수 있습니다.


쉽게 예시를 한 번 들어보도록 하겠습니다.


디지털화된 이미지를 컴퓨터가 처리할 때는 위와 같이 처리합니다. 우리는 아주 화려하고 멋진 사진이 보이지만, 컴퓨터는 이렇게 숫자로 된 것을 화면에 띄우는 것 뿐입니다. 위 화면에 나온 숫자는 10 x 10 pixel 크기의 임의의 이미지로 우리는 이 이미지를 처리하기 위해 Matrix(행렬)를 사용합니다.


위 Matrix도 그 위에 있는 Matrix와 흡사하지만 뭔가 다릅니다. 점의 갯수가 10칸이 아니죠? 하지만 위 Matrix는 10 x 10 Pixel의 이미지입니다. 그런데, 왜 가로 30개, 세로가 30개인 걸까요?


이미지에는 채널이라는 것이 존재합니다. 채널은 쉽게 말하면 이 이미지가 1채널 이미지인지, 3채널 이미지인지 말하는 것입니다. 그것은 어떤 차이냐구요? 여러분들이 잘 알고 있는 RGB의 채널입니다. 1채널이면 흑과 백, 즉 흑백 이미지처리인 것이고, 3채널이면 RGB 혹은 RGBA까지해서 총 빨강, 초록, 파랑색으로 컬러 이미지를 처리하게 됩니다.


즉, 똑겉은 10 x 10 픽셀의 이미지이지만 가로 10칸, 세로 10칸의 행렬은 1채널 이미지(흑백), 

그 아래에 있는 것은 3채널 이미지(컬러)인 것입니다.



OpenCV 기본 클래스

자 이제 컴퓨터가 어떻게 디지털화된 이미지를 처리하는지에 대한 기본적인 개념 설명이 충분히 되어졌을 것이라 생각하고, 이제 실전 코딩에 들어가기 위해 OpenCV에서 사용하는 몇 가지 기본 클래스에 대해 알아보도록 하겠습니다.


기본 클래스 파트는 포스트를 끄적거릴(?) 때마다 매번 설명할 것입니다. OpenCV에서 사용하는 클래스가 한 두가지가 있는 것도 아니고, 쉬운 설명을 위해서 각각의 사용법과 어떨 때 사용을 하면 좋을지에 대한 숙지가 중요하기 때문에 오늘은 기본적으로 간단히 디지털화된 이미지를 처리할 수 있는 클래스인 Mat 클래스에 대해서만 설명하도록 하겠습니다.



Mat 클래스

Mat 클래스는 C++ STL에서 가장 많은 부분을 차지하고 있는 클래스입니다. 아까 위에서 봤던 숫자로 된 디지털화된 배열들은 모두 Mat 클래스로 구현한 행렬입니다. 이 Mat 클래스로는 1채널 또는 다채널의 상수, 복소수, 행렬, 영상 등의 수치 데이터를 표현하는 n 차원 행렬 클래스입니다.


실제로 OpenCV 2.4 버전에서는 C++ STL에서 정식적으로 제공하는 Mat 대신 CvMat이라고 하는 C 구조체를 사용한 것이 있습니다. 물론 3.x 버전에서 이를 사용하지 못하는 것은 아니지만 3.x 버전을 사용하고 있다면 C++의 기본 API 사용을 추천합니다.


또, 기존에 CvMat을 사용해 구현한 이미지를 위해 OpenCV 3.x 버전에서는 cvarrToMat이라는 함수를 통해 CvMat이나 IplImage 등을 Mat으로 변환시켜주는 매우 좋은 함수를 제공합니다. 차후 포스트에서 해당 함수를 사용하는 자세한 방법을 다룰 것입니다.


그럼 이제 Mat 클래스를 사용하는 방법을 알아봅시다.



Mat 클래스를 이용해 변수를 생성합니다. 가장 기본적으로는 아무런 생성자 없는 기본 생성자를 이용해 생성하는 방법으로, 거기에 create라는 클래스 함수를 이용하여 정해진 크기와 자료형으로 생성할 수 있습니다. 


요소를 삽입할 때는 at이라는 클래스 함수를 사용해 요소를 삽입할 수 있습니다.


이 외에 여러가지 방법으로도 Mat 클래스를 사용할 수 있습니다. 원하는 데이터를 배열 변수를 통해서 삽입할 수도 있고, Scalar 자료 구조를 이용해서도 사용이 가능합니다. 요소 삽입에 대한 자세한 사용 방법은 차후 포스트를 통해서 더 알아볼 것입니다.


다만 Mat 클래스를 사용할 때도 몇 가지 주의해야할 사항이 있습니다.


위 코드는 Mat 클래스를 사용해 배열로 data를 주어준 것입니다. 여기서의 문제점은 요소의 갯수는 9개인데, 10 x 10 크기의 Matrix를 생성했다는 점입니다. 아무래도 C++ 언어를 사용하고 있기 때문에 나머지 빈 요소의 값은 0이 아닌 쓰레기값으로 처리되게 됩니다. 이렇게 될 경우, 연산을 수행할 때 0의 요소로 연산이 수행되는 것이 아님을 주의해야 합니다.


그럼 간단한 예제로 단일 색깔의 이미지를 표현해보고, 포스팅을 마치겠습니다.


3 Channel의 Matrix 3개를 만들고, 각각 컬럭값을 삽입했습니다. Scalar의 경우, R, G, B가 아닌 B, G ,R 값의 순이기 때문에 빨간색을 넣고 싶다면 0번째 Scalar가 아닌 2번쨰 Scalar에 요소 값을 넣어주면 됩니다.

TAGS.
comments powered by Disqus

Tistory Comments 0