오늘은 이미지 속 픽셀(pixel)에 접근하는 방법에 대해 알아보겠습니다.
그 전에 픽셀이 무엇인지에 대해서 살펴보도록 하지요.
픽셀이란 디지털 영상에서 더이상 쪼갤 수 없는 최소 단위를 뜻하며 픽셀 또는 화소로 얘기합니다.
이미지의 가로/세로 사이즈를 줄인다는 말에서 사이즈가 바로 픽셀을 말하는 거죠.
아래 사진을 예로 보시게 되시면 640x480 크기의 이미지가 있으며. 픽셀의 수는 640x480 = 307,200 개가 되네요.
우리가 흔하게 보는 이미지는 대게 RGB인 3개의 채널의 혼합으로 이루어진 이미지 입니다.
여기서 RGB는 색상인 Red, Green, Blue를 뜻합니다.
이미지속 한 픽셀마다 RGB의 3가지 값이 혼합되어있습니다.
이 내용은 아래의 앵무새 그림을 보고 이해하시면 됩니다.
그렇다면 오늘의 주제인 이미지 픽셀에 접근하는 방법을 코드를 통해 알아보도록 하겠습니다.
* 본 코드는 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로 된 벡터값을 의미합니다.
코드의 결과는 아래와 같습니다.
< 정리글 >
오늘은 이미지 속 픽셀의 RGB 채널에 접근하는 방법을 알아보았습니다.
이 흐름을 이용하면 어떠한 영역에 접근하여 색상을 바꾸어 주거나 이미지 전체의 밝기를 조절할 수 있죠.
한가지 확실히 하고 넘어가야 되는건 위 코드의 결과는 RGB에서 1가지의 채널을 제외한 나머지 값을 0으로 만들어 나온
결과이며, 만약 각각의 채널을 따로 분리하여 1개 채널로 이미지를 보게 되면 회색 계열로 보이게 됩니다.
'OpenCV' 카테고리의 다른 글
[Opencv] 이진화 라벨링 (0) | 2020.04.09 |
---|---|
[Opencv] 이미지 파일에 텍스트 숨기기 - 스테가노그래피 (0) | 2020.04.03 |
[Opencv] 이미지 속 특정 영역 자르기 Range() (1) | 2020.03.29 |
[Opencv] 여러 장의 이미지 처리 glob() (0) | 2020.03.27 |
[Opencv] 히스토그램을 이용한 숫자 인식 (0) | 2020.03.22 |