Chapter 02. 동영상의 압축원리

 1. 압축방식

 동영상도 어차피 "연속적인 그림"이라고 볼 수 있는데, 이를 압축하지 않는다면 1분 정도의 동영상을 저장하면 그 용량이 1GB 정도가 될 것입니다. 따라서, 동영상은 필수적으로 압축과정을 거칠 수 밖에 없습니다.

 1) 비손실 압축과 손실 압축

 압축방식에는 비손실 압축과 손실 압축이 있습니다.

비손실 압축이란, 프로그램이나 데이터등의 압축에 사용되는 zip, rar 등등의 압축방식이 있으며 원본 그대로를 압축하기 때문에 압축을 풀면 원본에서 전혀 손상되지 않은 데이터를 그대로 복원하게 됩니다.

손실 압축이란 압축되지 않은 그림 파일인 BMP파일을 JPG로 압축하는 경우를 생각하시면 되겠습니다. 이런 형태의 압축은 원본의 일부분을 변경하는 식으로 압축이 이루어지는 것이기 때문에 절대 원본과 똑같이 되돌릴 수 없습니다. 간혹, RM파일같이 압축률은 매우 높지만 화질은 떨어지는 동영상을 mpeg등의 형태로 바꾸면 화질이 좋아지지 않을까 생각하는 초보분들을 보는데 RM 파일 자체가 이미 손실 압축된 상태이기 때문에 이를 mpeg으로 만든다고 해도 용량만 커질 뿐 화질을 더 좋게 만들 수는 없는 것입니다.(물론, 이런 변환과정에서 화질 향상을 위해 여러 가지 필터들을 적용해서 약간의 효과를 볼 수는 있지만, 화질 좋은 원본을 압축한 것과는 비교할 수 없는 수준입니다.)

 2) 공간적 압축과 시간적 압축

 그림 파일의 압축에서 사용하는 압축원리는 몇 개의 유사한 색깔을 띄는 점들을 묶어 평균적인 색깔을 띄는 블록으로 바꾸는 경우가 주로 사용되는데 이런 압축방식을 공간적 압축이라고 합니다.

동영상의 압축에서는 이런 공간적 압축은 물론이고, 시간적인 압축 방식도 사용되는데, 키프레임(Key Frame)과 델타 프레임(Delta Frame)을 이용하는 방법을 쓰고 있습니다.

 3) 키 프레임(Key Frame)과 델타 프레임(Delta Frame)

 앞서 설명한 바와 같이 디지털 동영상의 경우에는 공간적 압축에 부가해 시간적 압축도 사용하는데, 그 원리가 Key Frame과 Delta Frame입니다.

 

시간적으로 압축되지 않은 동영상
 
위의 그림은 시간적으로 압축되지 않은 동영상을 보여줍니다. 5개의 프레임이 모두 완전한 그림임을 볼 수 있습니다.

 

시간적으로 압축된 동영상
 
그러나 위의 그림처럼 시간적으로 압축된 동영상의 경우는 ①번과 ⑤번만 완전한 그림이고 2,3,4번은 완전하지 않은 그림임을 볼 수 있습니다.
이때 ①번과 ⑤번처럼 완전한 그림은 Key Frame이며, 2,3,4번처럼 완전하지 않은 그림은 Delta Frame이 되는 것입니다. 이 델타 프레임은 키 프레임에서 변경된 부분의 정보만을 담고 있는 것이며, 5번째에는 1번에서 변경된 정보의 양이 너무 많아 완전한 화면이 되었고, 결국 다시 키프레임이 된 것입니다.
이렇게 연속되는 프레임들을 키 프레임과 델타 프레임으로 나누게 되면, 모든 프레임을 완전한 프레임으로 만드는 방식보다는 훨씬 용량을 줄일 수 있습니다. 이런 압축방식을 시간적 압축이라고 합니다.
DivX를 비롯해 mpeg등의 동영상은 모두 이런 시간적 압축방식을 채택하고 있는데, 여기에는 몇가지 문제점이 있습니다. 대표적인 것은, 동영상중 일부분을 끊어내거나 특정 위치로 바로 이동해 재생하는 등의 조작을 할 때 반드시 키 프레임이 있어야 델타 프레임의 재생이 가능한 것입니다. 만약, 키 프레임이 없는 상태의 델타 프레임만 있다면 이때에는 기준은 없고 기준에서 변화된 부분에 대한 데이터만 있는 것이라서 재생이 제대로 되지 못합니다.
결론적으로 DivX를 비롯한 동영상의 편집시에는 반드시 키프레임에서 끊고, 이어야 제대로 된 파일이 만들어지게 되는 것입니다.
 
4) VKI(Variable Key Frame Interval)
 
동영상 인코딩시 키 프레임은 델타 프레임보다 많은 용량을 가지게 됩니다. 따라서, 키 프레임의 수를 줄이는 것은 용량을 줄이는 효과가 있습니다.
대체로, 키 프레임은 일정한 간격으로 들어가도록 인코딩되는 경우가 일반적이지만, 동영상은 다양한 장면들을 담고 있기 때문에 이런 방법이 비효율적인 경우가 많습니다.
배경이나 동작의 변화가 아주 적은 장면이 지속되는 부분에서 쓸데없이 키 프레임이 많이 들어가는 것은 용량의 낭비일 뿐이며, 동작의 변화가 심한 장면에서 키 프레임을 일정한 간격으로 넣게 되면 키 프레임보다 오히려 델타 프레임의 크기가 더 커지는 상태가 됩니다.
따라서, 동작 변화가 심한 부분은 키 프레임을 보다 자주 넣고 동작 변화가 적은 부분에서는 키 프레임을 가끔씩 넣는 식으로 키 프레임의 간격을 가변적으로 하면 용량을 줄일 수 있는 효율적인 방법이 될 것이며, 이런 방식을 VKI(Variable Key Frame Interval)이라고 합니다.
 
본래 DivX 3.11a 코덱에서는 일정한 시간간격으로 키프레임을 넣도록 만들어져 있으나, 이것을 개량해 자동적으로 키 프레임을 변화시킬 수 있는 형태로 변경한 코덱이 개발되었으며 DivX VKI patch 또는 DivX 3.20 코덱으로 알려져 있는 것입니다.
현재 널리 사용되고 있는 SBC 인코딩 방법에서는 DivX 3.20 코덱을 쓰지 않고 DivX 3.11a를 그대로 사용하면서 보다 향상된 VKI 기능을 적용할 수 있습니다.
또한, DivX 4.x 코덱은 자체적으로 VKI 기능을 내장하고 있습니다.
 
2. 코덱(Codec)
 
1) 코덱이란?
 
아마도, 동영상과 관련해 가장 많이 듣게 되는 말이 "코덱(Codec)"일 것입니다. 초보분들의 경우에는 도대체 코덱이 뭔가 대단히 궁금해 하시는 분들이 많은데, 이는 동영상의 압축/복원 방식 또는 프로그램을 말합니다.
동영상은 필수적으로 압축과정을 거칠 수 밖에 없으며, 이렇게 압축된 데이터를 복원하는(압축을 푸는) 과정이 있어야 재생이 가능한 것입니다. 코덱(CODEC)은 이런 압축(COmpress)과 복원(DECompress)이라는 단어의 합성어입니다. 그런데, 이런 압축 방법 또는 프로그램들이 워낙 다양하다보니 수많은 코덱들이 생겨나게 되었으며, 지금 이 시간에도 어디선가는 새로운 코덱이 개발되고 있을 것입니다.
 
자물쇠는 그 자물쇠에 맞는 열쇠로 열어야 하듯이, A라는 코덱으로 만들어진 동영상은 A라는 코덱이 컴퓨터에 설치되어 있어야 재생이 가능한 것입니다.
 
2) DivX;-) 코덱은?
 
DIVX는 본래 대여용 동영상 매체에 관한 프로젝트였습니다만, 이는 그 프로젝트 자체가 없어져 버렸기 때문에 완전히 사장된 것입니다.
현재의 DivX;-) 코덱은 처음의 DIVX와는 이름만 같은 뿐 아무런 연관성이 없습니다. 이 코덱은 Microsoft社 (이하 MS로 씁니다.)의 mpeg4 코덱을 몇 명의 해커들이 해킹해 만들어낸 것으로 기본적으로는 MS의 mpeg4 코덱과 완전히 같습니다.
♣ Mpeg4는 실제로는 동영상 관련 기술 표준을 의미합니다만, 대체로 Mpeg4라면 MS의 코덱을 지칭하는 것으로 쓰이고 있습니다. ♣
이 DivX;-) 코덱은 압축률이 워낙 뛰어나기 때문에 현재 일반적으로 사용되는 영상매체로는 가장 화질이 뛰어나다는 DVD를 이 코덱을 사용해 재 압축하면 원본보다 화질은 약간 떨어지지만 용량을 대폭 줄일 수 있는 이점이 있어 각광을 받기 시작했습니다.
몇 차례의 버전업을 거친 후 마지막으로 릴리즈(release)된 버전이 DivX;-) 3.11 alpha 코덱입니다. (2001년 현재)
이 코덱은 Low motion과 Fast motion 이라는 두 개의 코덱이 한 세트를 이루고 있는 형태입니다. 이중에서 Low motion 코덱은 대체로 느린 동영상에 적합하고, Fast motion은 빠른 동영상에 적합하다고 하지만, 실제로는 Fast motion의 경우 화질에 문제가 있어 거의 사용되지 않습니다.
그 이후로는 Project Mayo 라는 새로운 팀을 조직해 MS의 mpeg4 코덱을 기반으로 한 것이 아닌 독자적인 코덱의 개발을 진행하고 있는데, 새로 개발될 코덱의 이름은 DivX DUEX로 알려져 있었습니다. 이 개발과정의 일환으로 중간단계의 시험용 코덱들이 지속적으로 공개되었는데 이 코덱들은 소스코드까지 공개되기 때문에 Open DivX코덱으로 불립니다.
Open DivX 코덱 이외에도 3ivX 코덱, Angelpotion 코덱, Kristal 코덱 등등의 수많은 mpeg4 코덱들이 나오고 있으며, 최근에 Project Mayo 그룹에서 개발한 DivX 4.x 코덱이 나왔습니다.
한가지 아쉬운 점은 예전의 Open DivX 코덱과 달리 DivX 4.x 코덱은 소스코드가 공개되지 않았으며, 일부 시스템 또는 동영상 관련 프로그램 등과 문제가 발생하는 경우가 있는 것으로 알려져 있습니다. 따라서, 어떠한 코덱도 완벽이란 없다고 할 수 있겠습니다.
 
3. 비트 레이트(Bit Rate)
 
비디오 및 오디오의 품질에 가장 큰 영향을 주는 것은 bit rate입니다. 이것은 비디오나 오디오를 인코딩할 때 사용되는 데이터의 양(kb/s)을 말하며, 이 수치가 높을수록 질은 좋아지나 용량은 급증하게 됩니다.
물론, 앞서 설명한 바와 같이 화면크기도 용량에 영향을 주지만, 비트레이트가 훨씬 더 큰 영향을 미치기 때문에 결국 DivX의 화질과 용량은 거의 이것에 의해 좌우된다해도 과언이 아닙니다.
 
1) CBR(Constant Bit Rate)
 
이것은 말 그대로 고정된 bit rate를 적용하는 경우입니다. 가장 대표적인 예가 MP3 오디오에서 볼 수 있는 128kb/s 또는 160kb/s 같은 형태입니다. 이렇게 고정된 bit rate를 사용하는 경우에는 재생시 안정적이긴 하지만, 별로 데이터가 많이 필요 없는 부분에서는 데이터의 낭비가 일어나고 데이터가 많이 필요한 부분에서는 질이 떨어지는 문제가 있습니다.
일반 VCD에서 사용하는 mpeg 형식의 동영상은 1150kb/s의 CBR 형태로 되어 있습니다. 하지만, DivX;-) 3.x 및 DivX 4.x 코덱은 CBR이 아닌 VBR 방식을 사용하고 있습니다.
 
2) VBR(Variable Bit Rate)
 
이것은 CBR의 단점을 개선하기 위한 방안으로 나온 것으로 비디오나 오디오 데이터의 부분마다 필요한 데이터량이 적어도 될 부분은 비트레이트를 줄이고, 데이터량이 많이 필요한 부분에서는 비트레이트를 늘리는 방식으로 가변적인 비트레이트를 사용하는 형식입니다. 비디오를 예로 들자면, 빠른 동작에서는 비트레이트를 크게하고 느린 동작에서는 비트레이트를 줄이는 식입니다.
DivX 코덱은 기본적으로 VBR 형식으로 되어 있기 때문에 CBR 형태인 VCD보다 용량을 줄일 수 있는 것입니다.
♣ 최근에는 DivX 4.x 코덱을 사용한 인코딩 방법 중에 2pass VBR 이라는 방법이 있기 때문에 DivX 4.x 코덱을 사용한 경우에 VBR 이란 말을 붙이는 경우가 많습니다만, 본래 모든 DivX 코덱은 다 VBR 식입니다.
DivX 동영상에서 오디오는 본래 CBR MP3 형식을 사용해 왔었습니다만, 현재는 예전과 달리 이 오디오 부분도 VBR MP3 형식으로 인코딩하는 프로그램들이 개발되어 있으므로 보다 효율적인 오디오 인코딩이 가능해 졌습니다.
 
3) ABR(Average Bit Rate)
 
이 형식은 VBR과 유사한 형태이나 VBR이 비트레이트의 변동폭을 지정해 인코딩 되는 데 반해서 이 형식은 목표로 하는 평균적인 비트레이트만을 지정해 준 다음 프로그램이 자동적으로 지정된 평균 비트레이트 수치에 근접하게 비트레이트를 변경시켜가면서 인코딩하는 방식입니다.
이런 방법은 주로 MP3 오디오 인코딩에 적용되며, 엄밀하게 따지자면 DivX 동영상 코덱의 VBR도 이 방식과 유사하다고 할 수 있겠습니다.
 

내용출처 : Hananet Movie Club CINE   DivX Total Manual V4.2

'멀티미디어 > 일반 자료' 카테고리의 다른 글

Chapter 06. DVD와 DivX  (0) 2009.03.18
Chapter 05. 오디오(Audio)  (0) 2009.03.18
Chapter 04. DivX 인코딩과 Deinterlacing / IVTC  (0) 2009.03.18
Chapter 03. Telecine & IVTC  (0) 2009.03.18
Chapter 01. 프레임(Frame)  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

 Chapter 01. 프레임(Frame)

 1. 프레임(frame)이란?

 동영상의 기본이 되는 영화를 기준으로 생각해 보면, 영화 영상은 결국 필름에 연속적으로 찍힌 한 장 한 장의 사진을 일정한 속도로 돌려가면서 영사해 움직이는 영상을 만들어 내는 것입니다. 이 때 한 장 한 장의 사진을 본다면 당연히 정지된 상태일 것입니다. 이렇게 동영상을 구성하고 있는 정지된 화면 하나 하나를 프레임이라고 합니다.

 2. 프레임 레이트(frame rate)

 정해진 시간 동안에 몇 프레임을 보여주느냐 하는 것을 frame rate라고 하는 데 대체로 fps(frame per second; 초당 프레임수)로 표시하며, 이는 동영상 매체별로 다릅니다. 영화의 경우 24fps이며, 우리나라나 미국의 표준방식인 NTSC방식의 DVD는 29.97fps, 유럽지역에서 주로 쓰는 PAL방식은 25fps로 되어 있습니다.

 3. 픽셀(Pixel)수

 동영상의 화질을 결정하는 요소 중 하나는 화면의 크기 즉, 픽셀(pixel)수 입니다. 동영상의 각 프레임은 수많은 점(點; pixel)로 구성되어 있으며, 이 픽셀의 수에 따라 화면의 크기가 달라집니다. 픽셀수가 많으면 당연히 화질이 좋겠지만, 그에 비례해 용량이 증가하게 됩니다. 우리나라의 표준방식인 NTSC방식의 DVD는 720(가로)x480(세로)의 픽셀로 구성되어 있습니다. 그러나, DivX 동영상에서는 대체로 이를 그대로 사용하지 않습니다. 왜냐하면, 픽셀수를 어느 정도 줄여도 컴퓨터나 모니터나 TV등으로 감상하는데는 눈에 띄일 만큼의 화질저하가 없으며 용량은 줄일 수 있기 때문입니다. (참고로, Matrox G400 계열의 VGA 카드를 사용하는 일부 시스템에서는 36의 배수가 되는 픽셀수, 즉 720픽셀을 제대로 재생하지 못해 에러가 발생하는 경우도 있습니다. 이런 경우에 사용되는 패치 파일이 나와 있으므로 패치를 해 주어야 제대로 재생이 가능합니다.)

 4. 화면비(Aspect Ratio)

     화면비란 프레임의 [가로 : 세로] 의 크기 비율을 말합니다.

 1) 영화의 화면비

 a. 1.33 : 1 (4 : 3) - 스탠다드

 1950년대까지 영화의 표준 화면은 1.37:1 이었습니다. TV가 개발되면서 이것을 모방한 1.33:1 을 표준화면으로 삼았고 그 이후로 지금까지 계속해서 표준으로 자리잡고 있습니다.

 b. 2.35 : 1 - 시네마스코프

 50년대에 TV가 영화의 적으로 대두되자 거기 대항하기 위해 개발된 와이드스크린입니다.

기존의 35mm필름을 그대로 사용하면서 화상을 가로로 압축해 저장하는 아나모픽(Anamorphic)방식의 개발로 기존의 두배에 가까운 넓은 화면을 담을 수 있게 되었는 데, 렌즈만 교체해주는 방식으로 기존 35mm와 호환이 가능하므로 그 이후로 현재까지도 표준으로 자리잡고 있습니다.

시네마스코프는 원래 특정 영화사의 상표명이지만, 지금은 2.35:1 와이드스크린을 통칭하는 말로 쓰이고 있습니다.

 c. 2.2 : 1 - 70mm

 기존 35mm보다 실제로 두배가 넓은 70mm 필름을 사용해 Anamorphic 같은 편법이 아닌 진정한 와이드 스크린을 구현한 방식입니다.

필름의 양쪽 가장자리에 6채널의 스테레오 사운드트랙이 들어가기 때문에 화면은 Anamorphic 보다는 조금 짧은 2.2:1 입니다. (70mm에 아나모픽을 적용한 2.76:1 의 벤허같은 영화도 있지만 대부분 극장들이 상영시설을 제대로 갖추지 못한 탓에 대부분의 경우 벤허도 2.2:1 로 상영되었습니다.

70mm는 고화질의 화면과 웅장한 입체음향으로 사랑을 받았지만 제작이나 상영에 고가의 별도 장비가 필요한데다 35mm 필름의 질이 점점 개선되고 돌비스테레오(6채널을 4채널로 축소한 35mm용 입체음향)가 개발되면서 70년대 이후로는 거의 쓰이지 않게 되었습니다.

 d. 1.85 : 1 / 1.66 : 1 - 비스타비전

 비스타비전은 시네마스코프에 대항해서 라이벌 영화사가 개발한 또 다른 와이드스크린 방식으로 2.35:1 과 1.33:1 을 절충한 화면입니다. 원래는 특수한 필름과 카메라를 사용해서 초 고화질을 구현한 방식이지만, 비호환성으로 인해 사장되어 버리고 요즘은 특수효과 촬영등의 특별히 고화질이 필요로 한 부분에서만 부분적으로 사용될 뿐 이름만 남아서, 일반 35mm필름에다 비스타비전의 화면비율로 촬영한 영화들을 흔히 비스타비전, 또는 비스타 사이즈라고 부릅니다.

요즘 극장에서 가장 일반적으로 볼 수 있는 방식입니다. 이유는 잘 모르겠지만 미국과 그 영향권에 있는 나라들에서는 1.85:1을 선호하고, 유럽쪽에서는 1.66:1을 선호합니다. 그래서 유럽영화가 미국에서 개봉하면 화면 위아래가 잘리곤 합니다. (디즈니의 애니메이션 DVD들은 극장에서는 1.85:1로 상영했는데도, 보통 1.66:1인 상태로 출시됩니다.)

 e. 1.78 : 1 (16 : 9) - 와이드 스크린

 흔히 하는 오해로 극장용 영화가 16:9라고 생각하는 일이 많은데, 실제로는 16:9의 화면비율을 가진 필름은 없습니다. 1.78:1은 와이드 TV의 표준 규격으로 유럽과 미국 비스타비전의 중간치에 해당합니다. (어느 특정한 한쪽 편을 들 수 없으니까 다같이 피보자는 취지로 그랬나 봅니다.)

정상적인 화면 비율을 유지한 상태라면 1.78:1 화면에서 1.66:1 영화는 화면 양쪽 옆으로 약간의 여백이, 1.85:1 영화는 위아래로 여백이 생겨야 합니다. 그런데 DVD 중에서는 16:9의 화면에 맞춰서 영화의 화면을 잘라버린 경우도 많이 있기 때문에 인코딩에 들어가기 전에 화면이 어떤 상태인지를 반드시 확인해야 합니다. (DVD의 표지에 표기된 화면비율이 잘못되어 있는 경우도 상당히 많으므로, 직접 눈으로 확인하는 것이 좋습니다.)

아주 드문 경우지만, 처음부터 필름이 아닌 형태로 제작된 영화(예를 들면 토이 스토리2) 중에는 원래 화면이 1.78:1인 경우도 있습니다.

 기타, 와이드 스크린의 초창기에는 여러가지 다양한 시도들이 있었기 때문에, 2.0:1, 2.55:1 등 다양한 형태의 화면비들도 존재합니다. 하지만 그런 것들은 모두 몇몇 작품에서만 실험적으로 사용되고는 사장되었기 때문에 소수의 몇 작품을 제외하고는 거의 찾아볼 수 없습니다.

그밖에 DVD 제작업자들이 원래의 화면을 무시하고 마음대로 잘라낸 특이한 화면들이 가끔씩 있습니다. 이런 것은 직접 보고 판단하는 수 밖에 없겠습니다.

 2) 16X16 Rule

 동영상을 다루는 과정에서 조심해야 할 것 중 하나는 원본 동영상의 화면비(Aspect ratio)와 16X16 룰(rule)입니다. 화면비를 제대로 맞춰주지 않으면 비정상적인 화면이 되니, 당연히 문제가 되겠지만 이와 아울러 신경써야 할 부분이 16X16 Rule 입니다.

16X16  규칙화면을 구성하는 픽셀수는 16의 배수로 맞추는 것을 기본으로 한다는 것입니다. 동영상을 다룰 때 사용되는 프로그램 또는 코덱에 따라서는 16의 배수가 아닌 픽셀 수는 아예 작업이 불가능한 경우도 있고, 반대로 어떠한 픽셀수든 상관없이 작업이 가능한 프로그램도 있습니다만, 되도록 16의 배수(불가피하다면 8의 배수)는 유지해 주는 것이 좋습니다. 특히, 가로 방향의 픽셀 수는 16의 배수로 설정하는 것이 대단히 중요합니다.

 

내용출처 : Hananet Movie Club CINE   DivX Total Manual V4.2


'멀티미디어 > 일반 자료' 카테고리의 다른 글

Chapter 06. DVD와 DivX  (0) 2009.03.18
Chapter 05. 오디오(Audio)  (0) 2009.03.18
Chapter 04. DivX 인코딩과 Deinterlacing / IVTC  (0) 2009.03.18
Chapter 03. Telecine & IVTC  (0) 2009.03.18
Chapter 02. 동영상의 압축원리  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

YCbCr과 YPbPr

 

색상신호를 RGB Color Space 상의 R, G, B의 색상 요소로 분해할 수 있는데, 우리는 눈에 보이는 대로 인식되는 이른바 "빛의 삼원색"에 너무나 익숙하다. 그런데, YCbCr이나 YPbPr은 색상신호가 아니라 휘도(Luminance) Y와 색차신호 Cb(Pb), Cr(Pr)에 기반한 색 표현 방식이다. 인간의 눈이 색상보
다 밝기에 더 민감하기 때문에 색차신호를 이용해서 처리하는 것이 효과적이다.

신호 표준들을 보면 Pb, Pr은 아날로그 색차신호를 호칭할 때 사용하는 용어이고 Cb, Cr은 디지털 신호로 부호화했을 때 사용하는 용어이다. 그런데 이를 혼용해서 부르는 경우가 많아졌다.

Cb/Cr과 Pb/Pr의 차이는 NTSC(480i)레벨의 신호단자를 [Y/Cb/Cr]로 표시하고, NTSC(480i)레벨 이상의 영상포맷(HDTV 720p,1080i)을 사용할 수 있는 단자를[Y/Pb/Pr]로 표시한다.

 현재 HDTV에서 사용하는 SMPTE-274M 표준의 YPbPr 신호의 수식은 다음과 같다.

Y = 0.2126*R + 0.7152*G + 0.0722*B

Pb = [0.5 / (1-0.0722)] * (B-Y)

Pr = [0.5 / (1-0.2126)] * (R-Y)

Y, Cr, Cb
CCIR 601 Coding System의 디지털 휘도신호와 색차신호이다. 휘도신호 Y는 13.5MHz으로 표본화되며, 2개의 색차신호는 휘도샘플 한 개를 공유하여 6.75MHz으로 표본화된다. Cr은 R-Y, Cb는 B-Y의 디지털화된 신호이다.

 다음은 RGB와 YCbCr 관계를 공식으로 표현한 것이다.

Y = 0.299*R + 0.587*G + 0.114*B
Cb = -0.16874*R - 0.33126*G + 0.5*B
Cr = 0.5*R - 0.41869*G - 0.08131*B

4:2:2
콤포넌트 비디오의 휘도(Y)와 색차신호(R-Y, B-Y)를 디지털화하는데 사용되는 표본화 주파수의 비율. 4:2:2라는 용어는 Y가 4번 표본화될 때 R-Y와 B-Y는 2번 표본화되는 것을 의미하는데, 이는 4:1:1에 비하여 휘도에 대한 색도대역 폭을 더 많이 할당한 것이다. CCIR 601에서 4:2:2 표본화는 디지털 스튜디오 장비의 표준으로서, 4:2:2와 CCIR 601이라는 두 용어가 일반적으로 동의어로 사용되지만 기술적으로 정확히 같은 의미는 아니다. Y의 표본화 주파수는 13.5MHz 이고, R-Y와 B-Y는 각각 6.75MHz로서 고품질 크로마키에 적합한 3.37MHz의 최대 가능 색대역폭을 제공한다.

 Composite 전송

3개의 영상신호를 합성하여 노란색인 하나의 선에 전송한다. 색을 분리하지 않고 합성하여 하나의 선으로 전송하기 때문에 화질이 가장 나쁘다. 흰색은 왼쪽 오디오, 빨간색은 오른쪽 오디오.

 S-Video (Super Video, Separate Video) 전송

3개의 영상신호를 밝기신호(Y)와 색차신호인 Cb, Cr(Pb, Pr)을 하나의 색신호(C)로 합성(Synthesized)하여 2개의 선으로 전송. Component 전송에 비해 화질이 좋으나 Component 전송보다 나쁘다.

전문가들은 S-Video가 아닌 Y/C(Brightness: 밝기신호 & Color:색신호) Video라 일컫는데, 이것이 비디오 신호 포멧을 좀 더 잘 표현하고 있기 때문이다.

 Component 전송

영상신호를 휘도(Y), 색차(Cb, Cr)의 세가지 성분(Component)으로 각각 분리하여 이를 3개의 선으로 보낸다. 화질이 가장 좋다.


'멀티미디어 > 이미지 프로세싱' 카테고리의 다른 글

YUV420을 RGB로 변환하기  (0) 2009.03.18
YUV420(YV12)  (0) 2009.03.18
동영상 파일끼리 PSNR 비교하는 프로그램  (0) 2009.03.18
DCT 프로그램  (0) 2009.03.18
H.264 tutoroals  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,
// RGB 값을 얻기위한 YUV 테이블을 만든다.
// YUV_B, YUV_R, YUV_G 배열은 사용하기 전에 YUV_lookup_table() 함수로 초기화해야 한다.

double YY[256], BU[256], GV[256], GU[256], RV[256];
unsigned char YUV_B[256][256];
unsigned char YUV_R[256][256];
unsigned char YUV_G[256][256][256];

void YUV_lookup_table()
{
    int i, j, k;
    double i_value;
    for( i=255; i>=0; i-- )
    {
        YY[i] = (1.164*(i-16.0));
        BU[i] = (2.018*(i-128.0));
        GV[i] = (0.831*(i-128.0));
        GU[i] = (0.391*(i-128.0));
        RV[i] = (1.596*(i-128.0));
    }

    for( i=255; i>=0; i-- ){
        for( j=255; j>=0; j-- )
        {
            i_value = YY[i] + BU[j];
            if ( i_value > 255 ) i_value=255;
            else if ( i_value < 0 ) i_value=0;
            YUV_B[i][j]=(int)i_value;

            i_value = YY[i] + RV[j];
            if ( i_value > 255 ) i_value=255;
            else if ( i_value < 0 ) i_value=0;
            YUV_R[i][j]=(int)i_value;
            for( k=0; k<256; k++ )
            {
                i_value = YY[i] - (GU[j] + GV[k]);
                if ( i_value > 255 ) i_value=255;
                else if ( i_value < 0 ) i_value=0;
                YUV_G[i][j][k] =(int)i_value;
            }
        }
    }
}

// YUV 영상을 RGB 영상으로 바꾸는 함수
void yuv420_to_rgb( unsigned char *in, unsigned char *out, int w, int h )
{
    int x,y;
    double imgsize = w*h;
    int w3 = w*3;
    double uvsize = imgsize/4.0;

    unsigned char *pY = in;
    unsigned char *pV = in + (int)imgsize;
    unsigned char *pU = in + (int)imgsize + (int)uvsize;

    int y00, y01, y10, y11;
    int u,v;    
    unsigned char *p;

   // 윈도우에서는 영상의 상하가 거꾸로 저장되지 때문에 아래와 같이 코드 작성.
    for( y=0; y<=h-2; y+=2 )
    {
        for( x=0; x<=w-2; x+=2 )
        {
            p = out + w3*(h-y-1) + x*3;
            u = *pU;
            v = *pV;

            y00 = *pY;
            y01 = *(pY+1);
            y10 = *(pY+w);
            y11 = *(pY+w+1);

            *(p)        = YUV_B[y00][u];
            *(p+1)      = YUV_G[y00][u][v];
            *(p+2)      = YUV_R[y00][v];

            *(p+3)      = YUV_B[y01][u];
            *(p+3+1)    = YUV_G[y01][u][v];
            *(p+3+2)    = YUV_R[y01][v];

            *(p-w3)     = YUV_B[y10][u];
            *(p-w3+1)   = YUV_G[y10][u][v];
            *(p-w3+2)   = YUV_R[y10][v];

            *(p-w3+3)   = YUV_B[y11][u];
            *(p-w3+3+1) = YUV_G[y11][u][v];
            *(p-w3+3+2) = YUV_R[y11][v];
            
            pU++;
            pV++;
            pY = pY + 2;
        }
        pY = pY + w;
    }

    // 일반적인 경우 아래의 코드 사용함.
    /*for( y=0; y<=h-2; y+=2 )
    {
        for( x=0; x<=w-2; x+=2 )
        {
            p = out + w3*y + x*3;
            u = *pU;
            v = *pV;

            y00 = *pY;
            y01 = *(pY+1);
            y10 = *(pY+w);
            y11 = *(pY+w+1);

            *(p)        = YUV_B[y00][u];
            *(p+1)      = YUV_G[y00][u][v];
            *(p+2)      = YUV_R[y00][v];

            *(p+3)      = YUV_B[y01][u];
            *(p+3+1)    = YUV_G[y01][u][v];
            *(p+3+2)    = YUV_R[y01][v];

            *(p+w3)     = YUV_B[y10][u];
            *(p+w3+1)   = YUV_G[y10][u][v];
            *(p+w3+2)   = YUV_R[y10][v];

            *(p+w3+3)   = YUV_B[y11][u];
            *(p+w3+3+1) = YUV_G[y11][u][v];
            *(p+w3+3+2) = YUV_R[y11][v];
            
            pU++;
            pV++;
            pY = pY + 2;
        }
        pY = pY + w;
    }*/
}


//////////////////////////////////////////////////////////////////////////////////////
// BMP 파일로 저장하기

        int rgbSize = _imageSize.cx*_imageSize.cy*3;
        BYTE* pRgb = new BYTE[rgbSize];
        memset(pRgb, 0, rgbSize);

        yuv420_to_rgb(_pImage, pRgb, _imageSize.cx, _imageSize.cy);

        /*TCHAR curDirPath[512];
        ::GetModuleFileName(NULL, curDirPath, 512);
        TCHAR* pExt = _tcsrchr(curDirPath, _T('\\'));
        if(pExt) *pExt = 0;*/

        TCHAR defExt[] = _T("bmp");
        TCHAR filters[] = _T("bmp Files(*.bmp)|*.bmp|All Files(*.*)|*.*||");
        DWORD flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
        TCHAR cd[_MAX_PATH];
        GetCurrentDirectory(_MAX_PATH, cd);

        CFileDialog dlg(FALSE, defExt, 0, flags, filters, this);
        dlg.m_ofn.lpstrInitialDir = cd;        
        if(IDOK == dlg.DoModal()){
            HANDLE hFile;
            hFile = CreateFile(dlg.GetPathName(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
            if (hFile == INVALID_HANDLE_VALUE){ 
                CString s; s.Format(_T("Could not create file : %s (error %d)\n"), dlg.GetPathName(), GetLastError());
                AfxMessageBox(s, MB_ICONSTOP|MB_OK);
                return;
            }

            int headerSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD);
            BITMAPFILEHEADER fileHeader = { ((WORD)('M'<<8)|'B'), headerSize + rgbSize, 0, 0,  headerSize};
            BITMAPINFOHEADER infoHeader = { sizeof(BITMAPINFOHEADER), _imageSize.cx, _imageSize.cy, 1, 24, BI_RGB, rgbSize, 0, 0, 0, 0 };
            RGBQUAD rgbQuad = { 0, };

            DWORD writtenLen = 0;
            if(FALSE == WriteFile(hFile, &fileHeader, sizeof(fileHeader), &writtenLen, 0)){
                CString s; s.Format(_T("Could not write file : %s (error %d)\n"), _T("File Header"), GetLastError());
                AfxMessageBox(s, MB_ICONSTOP|MB_OK);
            }

            if(FALSE == WriteFile(hFile, &infoHeader, sizeof(infoHeader), &writtenLen, 0)){
                CString s; s.Format(_T("Could not write file : %s (error %d)\n"), _T("Info Header"), GetLastError());
                AfxMessageBox(s, MB_ICONSTOP|MB_OK);
            }

            if(FALSE == WriteFile(hFile, &rgbQuad, sizeof(rgbQuad), &writtenLen, 0)){
                CString s; s.Format(_T("Could not write file : %s (error %d)\n"), _T("RGB Quad"), GetLastError());
                AfxMessageBox(s, MB_ICONSTOP|MB_OK);
            }
            
            if(FALSE == WriteFile(hFile, pRgb, rgbSize, &writtenLen, 0)){
                CString s; s.Format(_T("Could not write file : %s (error %d)\n"), dlg.GetPathName(), GetLastError());
                AfxMessageBox(s, MB_ICONSTOP|MB_OK);
            }
            CloseHandle(hFile);
        }        
        
        if(pRgb)    delete [] pRgb;

'멀티미디어 > 이미지 프로세싱' 카테고리의 다른 글

YCbCr과 YPbPr  (0) 2009.03.18
YUV420(YV12)  (0) 2009.03.18
동영상 파일끼리 PSNR 비교하는 프로그램  (0) 2009.03.18
DCT 프로그램  (0) 2009.03.18
H.264 tutoroals  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

참조 사이트: http://www.fourcc.org 

YUV에도 여러 가지 종류가 있다. 그 중에서 YUV420(YV12)에 대해서 알아보도록 하겠다.

YUV420(YV12)

This is the format of choice for many software MPEG codecs. It comprises an NxM Y plane followed by (N/2)x(M/2) V and U planes.

  Horizontal Vertical
Y Sample Period 1 1
V Sample Period 2 2
U Sample Period 2 2

 

 Positive biHeight implies top-down image (top line first)

ATI says they have a download which contains this codec but I can't find it on their site. If you would like something similar for Quicktime, try here.

=======================================================================================

// 아래 코드는 YUV 바이트 스트림 배열에서의 YUV 각 값의 위치를 찾기위한 코드가 설명되어 있다.

Height = 16;
Width  = 16;
Y'ArraySize = Height × Width;    // (256)
Y' = Array[7 × Width + 5];
U = Array[(7/2) × (Width/2) + 5/2 + Y'ArraySize];
V = Array[(7/2) × (Width/2) + 5/2 + Y'ArraySize + Y'ArraySize/4];

RGB = Y'UV444toRGB888(Y', U, V);

 

위 예제 그림은 Y -> U -> V 순으로 바이트 스트림이 되어 있지만 항상 정해진 것은 아니다.

다른 바이트 스트림의 경우 Y -> V -> U 순으로 되어 있는 경우도 있다.

  

YUV420 <------> RGB 변환

참고 사이트 : http://www.fourcc.org/fccyvrgb.php

 The following 2 sets of formulae are taken from information from Keith Jack's excellent book "Video Demystified" (ISBN 1-878707-09-4).

RGB to YUV Conversion

Y  =      (0.257 * R) + (0.504 * G) + (0.098 * B) + 16

Cr = V =  (0.439 * R) - (0.368 * G) - (0.071 * B) + 128

Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128

YUV to RGB Conversion

B = 1.164(Y - 16)                   + 2.018(U - 128)

G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128)

R = 1.164(Y - 16) + 1.596(V - 128)

#define clip(var) ((var>=255)?255:(var<=0)?0:var)

변환을 하면서 위와 같이 각 값에 대하여 clip이 필요하다.

'멀티미디어 > 이미지 프로세싱' 카테고리의 다른 글

YCbCr과 YPbPr  (0) 2009.03.18
YUV420을 RGB로 변환하기  (0) 2009.03.18
동영상 파일끼리 PSNR 비교하는 프로그램  (0) 2009.03.18
DCT 프로그램  (0) 2009.03.18
H.264 tutoroals  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

2,3개의 동영상 파일의 PSNR을 비교하는 프로그램입니다. 

프레임별로도 확인가능하다. 심플하면서 괜찮은것 같다..


'멀티미디어 > 이미지 프로세싱' 카테고리의 다른 글

YUV420을 RGB로 변환하기  (0) 2009.03.18
YUV420(YV12)  (0) 2009.03.18
DCT 프로그램  (0) 2009.03.18
H.264 tutoroals  (0) 2009.03.18
YUV 420 포멧 viewer 및 소스 파일  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

동영상 압축에서의 Integer transform(DCT)에 대한 C 소스입니다.

Fast DCT입니다.


블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

1. Avc Picturemanagement Draft 1

2. Overview

3. Loopfilter(Deblocking filter)

4. Inter prediction

5. Intra prediction

6. VLC(UVLC, CAVLC)

7. CABAC

8. Transform(DCT, Quantization)

블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,
YUV format 4:2:0 을 볼 수 있는 viewer 와 소스파일입니다. 

'멀티미디어 > 이미지 프로세싱' 카테고리의 다른 글

DCT 프로그램  (0) 2009.03.18
H.264 tutoroals  (0) 2009.03.18
JPEG 파일을 볼 수 있는 프로그램의 소스  (0) 2009.03.18
Modeling AWGN channel  (0) 2009.03.18
영상 처리 용어 해설  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,

Jpg 파일을 읽어서 decoding 한 후 디스플레이를 해주는 소스입니다.

JPEG decoding을 공부하는 데 도움이 될 수 있을 것도 같습니다.

 


'멀티미디어 > 이미지 프로세싱' 카테고리의 다른 글

DCT 프로그램  (0) 2009.03.18
H.264 tutoroals  (0) 2009.03.18
YUV 420 포멧 viewer 및 소스 파일  (0) 2009.03.18
Modeling AWGN channel  (0) 2009.03.18
영상 처리 용어 해설  (0) 2009.03.18
블로그 이미지

맨오브파워

한계를 뛰어 넘어서..........

,