오늘은 이미지 속 픽셀(pixel)에 접근하는 방법에 대해 알아보겠습니다.

 

그 전에 픽셀이 무엇인지에 대해서 살펴보도록 하지요.

 

픽셀이란 디지털 영상에서 더이상 쪼갤 수 없는 최소 단위를 뜻하며 픽셀 또는 화소로 얘기합니다.

 

이미지의 가로/세로 사이즈를 줄인다는 말에서 사이즈가 바로 픽셀을 말하는 거죠.

 

아래 사진을 예로 보시게 되시면 640x480 크기의 이미지가 있으며. 픽셀의 수는 640x480 = 307,200 개가 되네요.

 

640x480 이미지

 

 

 

우리가 흔하게 보는 이미지는 대게 RGB인 3개의 채널의 혼합으로 이루어진 이미지 입니다.

 

여기서 RGB는 색상인 Red, Green, Blue를 뜻합니다.

 

이미지속 한 픽셀마다 RGB의 3가지 값이 혼합되어있습니다.

 

이 내용은 아래의 앵무새 그림을 보고 이해하시면 됩니다.

 

 

RGB 벤다이어그램

 

RGB로 이루어진 이미지 

 

 

 

 

그렇다면 오늘의 주제인 이미지 픽셀에 접근하는 방법을 코드를 통해 알아보도록 하겠습니다.

 

* 본 코드는 Opencv 3.1.0 Version에서 사용하였습니다.

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main() {

	Mat img = imread("D:\\학교\\티스토리\\color\\mountain.jpg");

	Mat only_r = img.clone();
	Mat only_g = img.clone();
	Mat only_b = img.clone();

	for (int y = 0; y < img.rows; y++) {
		for (int x = 0; x < img.cols; x++) {	
			// B Channel => img.at<Vec3b>(y,x)[0]
			// G Channel => img.at<Vec3b>(y,x)[1]
			// R Channel => img.at<Vec3b>(y,x)[2]

			// Only Red 
			only_r.at<Vec3b>(y, x)[0] = 0; // zero B
			only_r.at<Vec3b>(y, x)[1] = 0; // zero G

			// Only Green
			only_g.at<Vec3b>(y, x)[0] = 0; // zero B
			only_g.at<Vec3b>(y, x)[2] = 0; // zero R

			// Only Blue
			only_b.at<Vec3b>(y, x)[1] = 0; // zero G
			only_b.at<Vec3b>(y, x)[2] = 0; // zero R
		}
	}

	imshow("원본 이미지", img);
	imshow("Only Red", only_r);
	imshow("Only Green", only_g);
	imshow("Only Blue", only_b);

	waitKey(0);
}

 

위 코드는 한 이미지를 불러와 RGB로 혼합되어 이루어진 이미지를 각각의 채널만을 남기고 나머지 채널은

0 값을 준 것입니다. 이렇게 코드를 돌려보면 위에 앵무새 그림과 동일하게 나오게 됩니다.

 

추가적으로 코드 내 Vec3b는 3 Byte로 된 벡터값을 의미합니다.

 

코드의 결과는 아래와 같습니다.

 

 

원본 이미지

 

Only Red
Only Green
Only Blue

 

 

 

< 정리글 >

 

오늘은 이미지 속 픽셀의 RGB 채널에 접근하는 방법을 알아보았습니다.

 

이 흐름을 이용하면 어떠한 영역에 접근하여 색상을 바꾸어 주거나 이미지 전체의 밝기를 조절할 수 있죠.

 

한가지 확실히 하고 넘어가야 되는건 위 코드의 결과는 RGB에서 1가지의 채널을 제외한 나머지 값을 0으로 만들어 나온

 

결과이며, 만약 각각의 채널을 따로 분리하여 1개 채널로 이미지를 보게 되면 회색 계열로 보이게 됩니다. 

 

 

+ Recent posts