본문 바로가기
vfxai 잡학지식 vfxai 잡학지식

HD 영상이 미묘하게 녹색·자홍으로 돌 때: Rec.601·Rec.709 YCbCr 행렬 착오

vfx 잡학지식 읽는 시간 약 8분 조회 1

HD 영상은 선명한데 피부와 붉은 물체가 살짝 초록빛이나 자홍빛을 띠면 색보정부터 만지고 싶어집니다. 하지만 밝기 곡선이나 레인지가 아니라 YCbCr 행렬을 잘못 읽은 경우도 있습니다. 행렬 오류는 색조를 바꿀 수 있습니다.

그렇다면 파일에서 어느 항목을 읽고, 편집기에서는 어떤 설정을 맞춰야 할까요? 세 단계를 따라가며 색이 달라진 지점을 가려 보겠습니다.

1. Rec.601과 Rec.709 YCbCr 행렬은 색 신호를 다르게 풉니다

영상 파일은 색을 RGB 세 값으로만 저장하지 않습니다. H.264나 ProRes 같은 영상은 흔히 YCbCr로 저장하고, 재생할 때 Y′CbCr 값을 R′G′B′로 바꿉니다. 이때 쓰는 변환식이 Matrix coefficients, 즉 행렬 계수입니다.

표준에 따라 Y′를 계산하는 가중치가 다릅니다. BT.601은 R′·G′·B′에 0.299·0.587·0.114를, BT.709는 0.2126·0.7152·0.0722를 적용합니다. 인코딩과 디코딩이 서로 다른 계수를 쓰면 밝기만 바뀌는 게 아니라 색 성분의 복원값도 달라집니다.

8비트 limited-range, 크로마 서브샘플링과 압축 손실이 없는 계산 예를 보겠습니다. 피부톤 예시 R′G′B′ 184, 122, 86을 BT.601로 부호화한 뒤 BT.709 행렬로 디코딩하면 190, 126, 83이 됩니다. 원본보다 빨강과 초록이 각각 6, 4 올라가고 파랑은 3 내려갑니다.

피부톤과 원색의 계산 결과

아래 값은 R′G′B′ 8비트 코드값입니다. Δ는 잘못된 행렬로 디코딩한 값에서 원본 값을 뺀 결과입니다. 피부톤은 예시 코드값이며 특정 인물이나 실제 촬영본의 측정값이 아닙니다.

원본 색·R′G′B′601 인코딩 → 709 디코딩
피부톤 예시
184, 122, 86
190, 126, 83
Δ +6, +4, −3
빨강
255, 0, 0
255, 24, 0
Δ 0, +24, 0
초록
0, 255, 0
0, 216, 0
Δ 0, −39, 0
자홍
255, 0, 255
255, 39, 255
Δ 0, +39, 0

반대로 BT.709로 부호화한 값을 BT.601로 읽으면 피부톤 예시는 179, 118, 88이 되고, 빨강은 233, 0, 2가 됩니다. 초록은 20, 255, 9, 자홍은 235, 0, 246으로 복원됩니다. 두 방향의 변화가 거울처럼 똑같지는 않습니다. 코드값 반올림과 0–255 범위 클리핑이 들어가기 때문입니다.

YCbCr 행렬 착오로 피부톤과 원색 RGB가 달라지는 계산 비교
BT.601과 BT.709 행렬을 서로 바꿔 계산한 RGB 코드값입니다. 8비트 limited-range, 크로마 서브샘플링과 압축 손실 제외. 실제 영상 캡처가 아닙니다.

이 예시에서 포화된 초록·자홍은 채널이 수십 코드까지 움직이지만 피부톤은 몇 코드 정도 바뀝니다. 행렬을 잘못 읽으면 색조 변화의 크기와 방향이 색마다 다릅니다. 중성 회색은 Cb와 Cr이 중립값이므로 이상적인 계산에서 그대로 남습니다. 따라서 회색까지 통째로 물들었다면 행렬만 원인이라고 단정하지 않습니다.

Rec.709와 sRGB가 같은 원색 좌표를 쓴다는 사실과, YCbCr 행렬이 같다는 말은 다릅니다. 색역과 전달 특성의 차이는 Rec.709와 sRGB가 어디서 다른지를 따로 구분해 보면 이해하기 쉽습니다.

2. Matrix coefficients와 레인지·전달 특성을 따로 확인합니다

MediaInfo를 열고 Video 항목에서 다음 네 줄을 찾습니다. 필드 이름이 비슷해도 뜻은 서로 다릅니다.

MediaInfo 항목무엇을 뜻하나확인할 점
Matrix coefficientsRGB와 YCbCr 사이의 변환 계수목표가 SDR Rec.709라면 의도한 값이 BT.709인지
Color primaries빨강·초록·파랑 원색의 좌표의도한 색역과 맞는지
Transfer characteristics신호의 전달 특성의도한 SDR/HDR 전달 특성과 맞는지
Color rangelimited 또는 full 코드 범위소스의 실제 범위와 해석이 맞는지

8비트 limited-range 영상은 명목상 Y′ 검정이 16, 흰색이 235이고 Cb·Cr의 중립값은 128입니다. Full과 limited를 반대로 읽으면 검정과 흰색 레벨이 달라질 수 있습니다. 레인지 착오는 행렬 착오와 다른 문제이므로 한 항목만 바꿔 해결하려 하지 않습니다.

MediaInfo에서 Matrix가 BT.601이나 SMPTE 170M 계열로 표시되고, 작업 의도는 BT.709였다면 확인할 단서입니다. 하지만 태그는 메타데이터가 보고하는 값입니다. 태그가 영상 픽셀을 실제로 검사해 맞다고 보증하지는 않습니다. 값이 비어 있거나 잘못 적힌 파일도 있으니 재생 프로그램이 자동으로 어떻게 해석하는지도 봐야 합니다.

명령줄을 쓴다면 ffprobe로 첫 번째 영상 스트림의 색 정보를 출력할 수 있습니다.

ffprobe -v error -select_streams v:0 -show_entries stream=color_range,color_space,color_primaries,color_transfer -of default=noprint_wrappers=1 input.mp4

color_space=bt709는 ffprobe의 색 공간 항목이고, color_range=tv는 limited, pc는 full을 뜻합니다. unknown이면 해당 정보가 파일에서 확인되지 않았다는 뜻이지, 자동으로 BT.709라는 뜻은 아닙니다. 해상도가 HD라는 이유만으로 태그가 정확하다고 가정하지 않습니다.

3. 소스 해석과 출력 변환을 한 쌍으로 맞춥니다

편집기에서는 소스 클립의 입력 색공간 또는 행렬 해석, 시퀀스·프로젝트의 작업 색공간, 내보내기 색공간과 레인지 설정을 차례로 확인합니다. 프로그램과 버전에 따라 메뉴 이름은 다릅니다. 항목이 여러 개라면 먼저 소스가 어떤 규격으로 부호화됐는지 확인한 다음 목표 출력 규격을 지정합니다.

여기서 주의할 점은 태그만 BT.709로 바꾸는 일은 픽셀을 BT.709로 변환하는 것과 다릅니다. 실제 데이터가 BT.601 행렬이라면 먼저 올바른 입력 행렬로 디코딩하고, 필요한 색 변환을 거친 뒤 출력 데이터와 메타데이터를 맞춰야 합니다. 태그만 덮어쓰면 재생기가 데이터를 읽는 방식만 바뀌어 오히려 색이 더 틀어질 수 있습니다.

같은 파일이 특정 플레이어에서만 달라 보인다면 원본 파일을 고치기 전에 재생기와 운영체제의 색 관리 차이도 확인합니다. 감마, 태그, 레인지 문제를 나누는 순서는 유튜브에 올린 뒤 색이 바래는 문제의 진단 절차와 함께 보면 좋습니다.

중간 마스터와 배포용 파일을 따로 내보내는 작업이라면 출력 단계마다 색공간 설정을 확인합니다. ProRes와 H.264의 역할을 나누는 방법은 렌더 파일과 업로드 파일을 고르는 기준에서 이어집니다.

4. 마지막 확인: 무엇을 어디서 고칠까

이제 처음 질문에 답할 수 있습니다. MediaInfo의 Matrix coefficients를 프로젝트의 소스 해석과 대조하고, Color range·primaries·transfer를 각각 확인한 뒤, 입력 해석과 출력 변환을 함께 맞춥니다. 행렬 오류는 밝기보다 색조를 바꿀 수 있습니다.

  • 색조가 밀리고 Matrix coefficients가 목표 규격과 다르면 소스 입력 행렬을 먼저 확인합니다.
  • 검정이 뜨거나 흰색이 눌리면 Matrix보다 Color range가 맞는지 봅니다.
  • 회색 중립축까지 색이 물들거나 앱마다 결과가 다르면 색 관리·전달 특성·플레이어 경로도 나눠 확인합니다.
  • 수정 뒤에는 짧은 테스트를 출력해 메타데이터와 실제 화면을 다시 확인합니다.

공개된 파일의 해상도나 파일명만으로 행렬을 정하지 말고, 메타데이터와 프로젝트 설정이 같은 규격을 가리키는지 맞춰 보십시오. 처음엔 색을 보정하지 말고, 먼저 행렬과 레인지를 확인합니다.

공식 문서와 도구 안내

vfx 잡학지식

함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.