최근 본 면접에서 면접관님으로부터 들었던 질문이 있다. 긴장해서 정확히 기억이 나지는 않지만 대략 이런 질문이었다.
"JPEG는 손실 압축 포맷인데, 어떤 방식으로 압축할까요?"
JPEG는 손실, PNG는 비손실 압축이라는 상식 정도만 알고 있었어서 많이 당황했고 몇 가지 추측에 기반해서 답변할 수 밖에 없었다.
면접을 마치고 JPEG 손실 압축 방법을 찾아보았다. 생각했던 것 보다 훨씬 영리하고 신박해서 놀라웠다.
JPEG 이미지 압축의 아이디어에는 몇 가지 핵심적인 아이디어가 내재되어 있었다.
0. 사진 특성상의 인접한 픽셀간의 데이터는 유사한 수치의 데이터인 경우가 많다. (Cosine transform시 low frequency 값이 많다.)
1. 사람의 눈으로 이미지를 인식할때 색차보다 밝기에 더 민감하다. (RGB -> YCbCr)
2. Discrete cosine transform + Quantization
4. Huffman coding
이해한 내용을 요약해서 정리하고자 한다.
1.
이미지 픽셀의 색상정보를 표현하는 방식 중 RGB가 일반적으로 친숙한 방식인 것 같다.
이러한 방법 이외에, YCbCr 이라고 밝기성분과 색차성분으로 색공간을 표현하는 방식이 있다.
YCbCr과 RGB는 상호 변환이 가능하다.
색상공간을 시각적으로 보면 유사함을 확인할 수 있는데 벡터 성분분해로도 상호변환 할 수 있을 것 같다.
민감한 Y값의 경우 보존하고 덜 민감한 Cb, Cr값만 다운 샘플링한다.
다운 샘플링이라는 것은 실제 정확한 색차정보를 모두 취하지 않고 샘플링 수를 줄인다는 의미이다.
다운샘플링은 4:2:0 / 4:1:1 / 4:2:2 방식이 있다.
2. Discrete cosine transform + Quantization
이 부분에서 재미있었다. 처음엔 무슨 소리지 하고 찬찬히 읽어보다가 진짜 영리하다고 생각했다.
Y, Cr, Cb Data들을 사용해서 function의 형태로 approximation 한다. 공학수학에서 Fourier 혹은 taylor series를이용한 approximation을 했었는데, 세상의 모든 함수는 이러한 series 형태로 'approximation'이 가능한 것으로 알고있다. DCT의 경우 다양한 주기를 가지고 있는 cosine 함수로 데이터를 근사시킨다. DCT 이후에는 다양한 주기를 가진 cosine series들의 계수들이 표시가 된다.
이때 저주파영역의 값들과 고주파 영역의 값들이 분리가되는데, 예를들어 cosx 는 저주파이고 cos7x는 주기가 짧으므로 상대적으로 고주파이다.
이미지의 특성상 저주파 영역의 계수값이 고주파 영역보다 크다. 즉 DCT로 표현된식에서 고주파의 계수가 상대적으로 절대값이 작다는 의미이다. 계수가 정말 낮은 값은 없애버려도 전체적인 파형에 영향을 아주 크게 미치지는 않는다.
이러한 원리로 여기서 이미지에 영향을 덜 미치는 고주파 영역의 데이터들을 날려버리는데, 컴퓨터 입장에서는 0~255사이의 값이라면 작은 값이던, 큰 값이던 동일한 byte수를 갖고 있기 때문에 아주 효과적으로 압축이된다.
JPEG에서는 이미지를 수 많은 8x8로 평면으로 나누고서 2-dimensional DCT 를 이용한다.
고주파 데이터를 날리는데는 Quantization을 이용한다. 압축방식마다 다양한 양자화 테이블이 있고 각기 다른 방법이 사용된다.
어렵지 않다. 그냥 나눠서 적당히 작으면 0값으로 날려버린다.
양이 많아서 허프만 코딩의경우 나중에 이어서 작성해보겠다..