색 공간
by DINHO
안녕하세요😊😊 오늘은 영상 신호 처리 기초, 그 중에서도 ‘색 공간’을 중심으로 이야기해 보겠습니다. 마지막에는 그레이 스케일을 이해할 수 있는 간단한 C언어 실습도 해보겠습니다.
-
이미지 기초
픽셀(Pixel)
이미지 데이터는 픽셀이라 하는 작은 이미지 직사각형 형태로 모은 것입니다. 각 픽셀은 한 가지 색의 직사각형이며 전체 이미지 크기는 (세로 픽셀 수 x 가로 픽셀 수) 형식으로 표현합니다. 한 픽셀 당 8bit의 값을 가집니다. 즉 0~255까지의 값에 따라 픽셀이 가지고 있는 정보가 다릅니다.
해상도
해상도는 우리가 흔히 화질, 선명도 등으로 부르며 이미지 따위가 표현된 섬세함의 정도를 나타냅니다. 보통 1인치 안에 표현되는 픽셀이나 점의 수로 해상도를 표현하며 널리 쓰이는 단위로 DPI와 PPI가 있습니다. 해상도가 높다는 말은 더 작은 픽셀로 이루어진 이미지를 구현할 수 있다는 말이고, 그에 따라 이미지를 더 섬세하고 자연스럽게 구현할 수 있습니다.
-
색 공간
색 공간이란 픽셀의 색을 숫자로 표현하는 방식을 말합니다. 대표적인 색공간으로는 그레이 스케일, RGB, YUV, HSV 방식 등이 있습니다.
그레이 스케일
그레이 스케일은 회색조라고도 불립니다. 그레이 스케일의 이미지는 각 화소의 빛의 양을 하나의 샘플인 이미지를 가리키며 광도의 정보만을 정합니다. 따라서 가장 여린 광도의 ‘검정’부터 가장 센 광도의 ‘백색’에 이르기까지 흑백 또는 단색화로 이미지를 나타냅니다.
아까 한 픽셀에 값이 0~255라고 했죠? 그레이 스케일에서 픽셀이 가지는 값이 0이면 검정이고 값이 255면 흰색입니다.
YUV
YUV는 휘도(Y), 청색 색차(U), 적색 색차(V) 정보로 색을 구성합니다. 이 때 Y 신호만 받게 되면 흑백 이미지가 됩니다. YUV는 맨 처음 컬러 티비가 나갈 때 사용했던 방법이고, 이미지를 압축할 때도 쓰는 방법입니다. 자세한 이야기는 추후에 자세이 이야기하겠습니다.
RGB
빛의 삼원색인 빨강(R), 초록(G), 파랑(B)으로 구성합니다. 변환 공식을 통해 YUV to RGB, RGB to YUV로 바꿀 수 있습니다. 이 내용도 오늘은 언급만 하고 추후에 C언어와 함께 다루도록 하겠습니다😉
-
그레이 스케일 with C
그렇다면 C언어를 통해 픽셀과 그레이 스케일에 대한 이해도를 높여보겠습니다. C언어를 통해 그레이 스케일을 한 눈에 이해할 수 있는 RAW 파일을 만들어보겠습니다.
#define _CRT_SECURE_NO_WARNINGS // fopen과 같은 잠재적으로 안전하지 않은 기능을 사용하여 발생하는 경고를 비활성화. #include <stdio.h> // 파일 작업을 위한 표준 입출력 라이브러리를 포함. #include <stdlib.h> // 메모리 할당 및 프로세스 제어를 위한 표준 라이브러리를 포함. int main() { unsigned char raw_image[512][512]; // 부호화되지 않은 문자의 2D 배열을 선언. 이 배열은 영상 데이터를 저장하는 데 사용됨. for (int i = 0; i < 512; i++) {// 이미지의 행에 걸쳐 반복. for (int j = 0; j < 300; j++) { // 현재 행의 처음 300개 열을 반복하여 그래디언트 효과를 만듦. float gradient = (float)j / 299; // 열 인덱스를 [0, 1] 범위로 정규화하여 그래디언트 값을 계산. raw_image[i][j] = (unsigned char)(gradient * 255); // 픽셀에 그래디언트 값을 적용하여 [0, 255] 범위로 스케일링. } // 나머지 열을 흰색으로 설정. for (int j = 300; j < 512; j++) { // 300번째 열부터 현재 행의 나머지 열을 반복합. raw_image[i][j] = 255; // 나머지 픽셀의 값을 255로 설정합니다. 이는 그레이스케일로 흰색을 나타냄. } } FILE* outfile = fopen("raw_image_example.raw", "wb"); //바이너리 모드에서 쓰기 위해 출력 파일 열기.wb = write binary. if (!outfile) { // 성공적으로 열었는지 확인. perror("Error opening file"); // 성공적이지 않다면 에러 메세지 출력. return 0; } fwrite(raw_image, sizeof(unsigned char), sizeof(raw_image), outfile); // raw_image 배열로부터 이미지 데이터 쓰기. fclose(outfile); // Closes the file. return 0; }
위 코드는 단순히 2차원 배열에 0~255의 값을 순차적으로 부여하여 그레이 스케일의 이미지를 만들어 냅니다. 이 그림은 단순하게 그라데이션을 나타내지만 더 정교하게 값을 부여하면 흑백 그림을 만들수도 있겠죠?? 위 코드에 대한 설명은 각 줄마다 최대한 자세히 주석을 달아두었습니다.
위 코드를 실행한 결과는 아래와 같습니다.
앞서 이야기했듯이 픽셀 값이 0이면 검정이고 255면 흰색입니다. 그라데이션 느낌이면 0부터 255까지 차례대로 증가하겠죠? 위 그림의 픽셀들이 담고 있는 값들을 보면 아래와 같습니다.
오늘은 영상 신호 처리 이론이라고 부르기도 부끄러울 정도로 아주 가볍고 쉬운 이론을 이야기해보고, C 코드 실습을 통해 이해해 보았습니다. 나중에도 C언어와 영상 신호 처리 이론에 대한 주제를 가져오도록 하겠습니다!!☺☺
Follow my github