해당 포스트는 "열혈강의 영상처리 프로그래밍" 책의 내용을 요약한 것이다.



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

I  = 0.595716R - 0.274453G - 0.321263B
Q = 0.221456R - 0.522591G + 0.311135B

YIQ 색 공간에서 RGB 색 공간으로 되돌리는 변환은 다음과 같다.


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

+ Recent posts