해당 포스트는 "열혈강의 영상처리 프로그래밍" 책의 내용을 요약한 것이다.
RGB나 CMY 색 공간은 공간을 이루는 축이 세 종류의 색깔이지만 YIQ, YUV, YCbCr은 색상의 특성을 이용하여 공간의 세 축을 구성한다. Y는 생상의 밝고 어두움을 나타내는 성분으로 사람 눈의 민감도를 고려하여 RGB 채널에 가중치를 준 것이다. 나머지 두 축은 색상 정보를 표현한다. 이러한 색 공간은 텔레비전 신호와 비디오 데이터 전송에 주로 사용된다.
※ YUV
Y축은 밝기 성분을 U,V 두 축은 색상을 표현한다. U 성분은 파란색에서 밝기 성분을 뺀 값이고, V 성분은 빨간색에서 밝기 성분을 뺀 값이다. RGB 색 공간에서 YUV 색 공간으로 변환하는 것은 RGB 각 채널에 가중치를 적용하여 더하는 방식으로 구한다.
Y = 0.229R + 0.587G + 0.114B
U = 0.492(B - Y)
= -0.14713R - 0.28886G + 0.436B
V = 0.877(R - Y)
= 0.615R - 0.51499G - 0.10001B
YUV 색 공간에서 RGB 색 공간으로 변환하는 것은 역행렬을 곱해주면 된다.
R = Y + 1.13983V
G = Y - 0.39465U - 0.58060V
B = Y + 2.03211U
※ YIQ
YUV와 같은 원리를 사용하며 RGB 색 공간으로부터 밝기 성분인 Y값을 구하는 방식도 같다. 차이는 색상 성분인 I, Q 값을 구하는 가중치로 YIQ 모델은 사람의 눈이 더욱 민감한 구간인 주황색에서 파란색 사이 영역을 식별하는 데 더 많은 데이터를 할당하기 위해 고안되었다. 다음은 RGB 색 공간에서 YIQ 색 공간으로 변환하는 식이다.
Y = 0.229R + 0.587G + 0.114B
R = Y + 0.9563I + 0.621Q
G = Y - 0.2721I - 0.6474Q
B = Y - 1.1070I + 1.7046Q
※ YCbCr 색 공간
디지털 텔레비전 시스템에 사용하는 색 공간으로 YPbPr 이라고 하는 아날로그 신호의 색 공간을 디지털화 한 것이다. 다음은 RGB 색 공간에서 YCbCr 색 공간으로 변환하는 식이다.
Y = 16 * 1/256 * ( 65.738R + 129.057G + 25.064B )
Cb = 128+ 1/256 * ( -37.945R - 74.494G + 112.439B )
Cr = 128 + 1/256 * ( 112.439R - 94.154G - 18.285B )
YCbCr 색 공간에서 RGB 색 공간으로 되돌리는 변환은 다음과 같다.
R = 1/256 * ( 298.082Y + 408.583Cr ) - 222.921
G = 1/256 * ( 298.082Y - 100.291Cb ) + 135.576
B = 1/256 * ( 298.082Y + 516.412Cb) - 276.836
※ YIQ 색 공간을 이용하여 영상 변환하기
컬러 영상을 회색조 영상으로 변환할 때가 있다. 예를 들어, 영사의 마스크를 이용하여 필터링으로 경계선을 추출한다고 할 때 회색조 영상을 이용하면 컬러 영상보다 더 적은 계산으로 결과를 얻을 수 있다. 컬러 영상을 회색조 영상으로 변환하는 방법으로는 RGB 세 채널 값의 평균을 구하는 것이다. 하지만 사람의 눈이 초록색에 더 민감하게 반응 하기 때문에 RGB 세 채널을 같은 비율로 다루는 것은 최적의 방법이 아니다. 우리가 여기서 살펴본 YIQ, YUV, YCbCr의 Y 값은 사람 눈의 민감도를 고려하여 RGB 채널에 가중치를 준 것이다. 그래서 Y 값을 이용하여 회색조 영상으로 변환하면 사람 눈에 더 알맞은 회색조 영상을 얻을 수 있다.
다음은 YIQ 색공간을 이용해서 컬러 영상을 회색조 영상으로 바꾸는 코드이다.
template <typename T> CMyImage<T> RGB2Gray(const CMyImage<T>& src) { ASSERT(src.GetChannel() == 3); int nWidth = src.GetWidth(); int nHeight = src.GetHeight(); CMyImage<T> dst(nWidth, nHeight); for (int r=0 ; r<nHeight ; r++) { T* pSrc = src.GetPtr(r); T* pDst = dst.GetPtr(r); int pos = 0; for (int c=0 ; c<nWidth ; c++) { pDst[c] = 0.114*pSrc[pos]+0.587*pSrc[pos+1]+0.299*pSrc[pos+2]; pos += 3; } } return dst; }
다음은 회색조 영상을 매개 변수로 하여 컬러 영상의 형식으로 변경 후 반환하는 함수이다. 영상의 형식만 변경할 뿐, 눈으로 보기에는 여전히 회색조 영상이다.
template <typename T> CMyImage<T> Gray2RGB(const CMyImage<T>& src) { ASSERT(src.GetChannel() == 1); int nWidth = src.GetWidth(); int nHeight = src.GetHeight(); CMyImage<T> dst(nWidth, nHeight, 3); for (int r=0 ; r<nHeight ; r++) { T* pSrc = src.GetPtr(r); T* pDst = dst.GetPtr(r); int pos = 0; for (int c=0 ; c<nWidth ; c++) { pDst[pos ] = pSrc[c]; pDst[pos+1] = pSrc[c]; pDst[pos+2] = pSrc[c]; pos += 3; } } return dst; }
'영상처리 프로그래밍' 카테고리의 다른 글
HSV 색 공간을 이용한 색감 조절 (0) | 2017.06.13 |
---|---|
색 공간(3) - HSV, HSL (0) | 2017.06.13 |
색 공간(1) - RGB, CMY (0) | 2017.06.13 |
영상의 채널 단위 접근과 변환 (0) | 2017.06.12 |
영상의 기하학적 변환 (0) | 2017.06.12 |