본문 바로가기

동영상 지식/심화지식

avs 스크립트 작성시 동영상 보정에 관해서

※이 글은 SmoothAdjust와 RGBAdjust를 이용한 개인적으로 선호해서 쓰고있는 동영상 레벨과 색감 보정방법에 대해 다루고 있습니다.




일단 설명에 앞서, 모니터가 과장된 레벨이나 색상을 보여주고 있지는 않은지 먼저 모니터 조정부터 하고 가실게요.

이 이미지를 보시면서 모니터의 밝기와 명암과 색상을 조절하시면 되구요
이런걸로 캘리의 효력은 없구요. 최소한 의도하지 않은 화면을 보여주는건 막아줍니다.
보통 색상은 기본값에서 안건드리셔도 될거구요. 밝기와 명암만 조정해주시면 될거에요.



↑이런식으로 모든 선들과 모서리들이 선명하면 맞는거고

↑이런식으로 나오시면 조정이 필요합니다.



모니터가 과장된 화면을 보여주지 않도록 조정을 다 하셨다면
이제 관련 기초 지식부터 설명해드릴게요.. 우선 색상에 관하여입니다.


먼저 컬러스페이스와 특성에 대해 설명해드릴게요.
보통 저희가 일반적으로 쓰는 컬러스페이스는 RGB입니다.
모니터도 한 픽셀에 빨강 초록 파랑색이 들어있지요.
빛의 삼원색으로서 각 색마다 8비트의 즉 256단계 0~255가지 광도를 표현할 수 있습니다.(3*8=24비트)
이 빨강 초록 파랑이 0~255단계로 각각 비율이 다르게 들어가면서 여러 색들을 표현하는거지요. RGB는 대부분 다 아실거라 생각합니다
그런데, 보통 흔히 보이는 압축 동영상에 쓰이는 컬러스페이스는 이 RGB가 아닙니다.
Y Cb Cr 이 쓰이는데요. Y는 광도이고, Cb는 블루색조 Cr은 레드 색조라고 이해하시면 편합니다. 이 Cb Cr의 혼합 비율로 색조 값을 갖게됩니다.

각 색조 값은 이러한 색들을 표현합니다.
그리고 Y로 어두움에서 밝음까지 광도를 표현하지요.
색조와 밝기가 합쳐져서 색상들이 나오는것입니다. (YV24(24비트)의 경우 RGB와 마찬가지로 각각 8비트가 쓰입니다.)

근데 왜 RGB가 안쓰이고 YCbCr이 쓰이냐면요, 사람의 눈이 밝기 변화에는 민감하지만 색상변화에는 그렇지 않기때문이여서 그렇다고 합니다.
YCbCr이 각각 8비트씩 쓰이는 RGB랑 같은 비트가 쓰이는 YV24는 일단 넘어가고요.
h264 압축표준에 쓰이는 YV12를 설명드릴게요. 이 컬러스페이스는요, YCbCr의 비율이 같지가 않습니다.
2x2 픽셀에서 4개의 픽셀 모두 Y의 정보가 들어가 있지만, CbCr의 정보는 1개만 들어 있습니다.
2x2 픽셀당 Y 32비트, Cb 8비트, Cr 8비트가 되는것이고 평균적으로 1픽셀당 8비트 2비트 2비트가 되는것이죠.(12비트 YV12)
2x2 픽셀당 한개의 색상을 가지고 있기 때문에 동영상 가로 세로 픽셀이 반드시 짝수여야 하는 것입니다.

1280*720의 경우 광도는 1280*720 해상도의 정보를 갖고 있지만 색상은 640*360 해상도를 갖고 있다는 것입니다.
하지만 사람은 색상에 민감하지 않아서 그 차이가 눈에 띄지 않는다는 것이죠. 이렇게 하여 획기적으로 동영상 용량을 줄이는겁니다.

위가 RGB이고 아래가 YV12입니다. 각각 초록과 파랑색이고 광도 200으로 같습니다.
보시다시피 YV12의 Y는 제대로 보존되어 글자의 픽셀계단은 선명하지만, 색상이 1/4이어서 글자색이 흐리고 배경색과 섞인게 보이실겁니다.
"뭐야 엄청 티나는데? 이런걸 왜쓰지" 하실지도 몰라서 이번엔 실사 사진으로 비교해드리겠습니다.

"이게 뭐지?"스럽지만 확실히 왼쪽은 RGB 24비트이고 오른쪽은 YV12 입니다... 쓰일만 하죠..



아래는 제가 직접 흑백 사진에 칼라를 입힌 이미지인데요,


원래는 이런 이미지였습니다.




근데 칼라 입힌걸 보시면 웃기실겁니다..





ㅇㅇㅋㅋ?? 사람 눈이 이정도로 색조에 둔감합니다 여러분..






여튼 RGB와 YCbCr이 다른점을 설명하고 싶었는데 쓸데없는 설명이 너무 길어졌네요.
다른점을 설명한 이유는 바로 컬러매트릭스 때문입니다. 동영상에는 YV12가 쓰이는데 모니터는 RGB입니다..
모니터는 빨초파 정보를 받아야 대는데 괴상한 광도랑 색조 정보만 갖고 있으니 어케 모니터에 표시할 방법이 없네여..?
그래서 YCbCr을 RGB모니터에서 볼 수 있게 RGB로 변환시켜주는 작업이 필요합니다.
이 작업을 렌더러가 하게 됩니다. 근데 RGB와 YCbCr간 변환시 어떻게 색을 대응시킬것이냐? 하는게 컬러매트릭스입니다.
주로 쓰이는 컬러매트릭스는 Rec.601과 Rec.709가 있습니다. 둘은 컬러스페이스를 RGB로 변환할때 서로 다른 변환값을 가집니다.
즉 Rec.601으로 RGB변환을 의도한 YV12 영상을 렌더러에서 Rec.709를 사용하여 RGB변환해서 재생해버리면 색상왜곡이 발생하는것이지요.
컬러스페이스가 중요한게, 보정을 하기 위해선 일단 왜곡없는 제대로된 색상을 봐야 하는게 먼저기 때문에 이렇게 설명드리는거에요.
보통 컴퓨터에선 Rec.601이 주로 쓰여 왔고 Avisynth 색상 필터도 Rec.601 기준으로 작동합니다만,
HD도입후 HD소스들이 Rec.709를 쓰는 관계로 각종 렌더러들이 Rec.709를 기준으로 재생하고 있는 상황이기에, Rec.709로 인코딩 하실것을 권장드립니다.
블루레이나 방송 TP 같은 HD소스는 원래 Rec.709이기 때문에 컬러매트릭스 변환을 안해주면 되겠습니다.
또한 보정시 꼭 AVSPmod로 맞는 매트릭스를 설정해서 미리보기 하시기 바랍니다.

참고로
Rec.709를 기본값으로 렌더하는 렌더러에는: 유튜브 플레시플레이어,JWP플래시플레이어,EVR(윈7,8 기본렌더러),Madshi렌더러,AVSPmod(HD소스의경우) 등이 있구요
Rec.601을 기본값으로 렌더하는 렌더러에는: 유튜브 html5 플레이어,Haali렌더러,크롬 html5 비디오,AVSP(구버전) 등이 있으니 참고하시기 바랍니다.
Madshi렌더러 같은 일부 렌더러는 동영상 파라미터 값에 있는 컬러매트릭스 정보를 참조하여 자동으로 올바른 컬러매트릭스로 렌더를 합니다.
수동으로 조절도 됩니다. Haali렌더러도 수동으로 조절가능


이제 level에 대해서 설명 드릴게요. luma range 즉 광도 범위에 대해서 설명할게요. 위에서 광도가 0~255 8비트가 있다는건 설명 드렸었죠.
근데 여기서 또 한가지 추가로 알려드릴것이 있어요. 바로 PC range와 TV range의 차이입니다. PC에선 0~255가 쓰이지만, TV는 16~235가 쓰입니다.
뭔말인고 하면. PC레인지에선 0이 완전 검정색이고 255가 완전 흰색인 반면에, TV레인지에선 16이 완전 검정이고 235가 완전 흰색이 되는거에요.
일반 동영상은 TV레인지이고 렌더러도 대부분의 렌더러가 TV레인지로 재생을 하게 됩니다. (PC에서 RGB 녹화한 영상 같은건 PC레인지입니다.)
Histogram("levels")를 보시겠습니다.

이런식으로 나오게 됩니다. 여기서 알아야 할 개념은 exposure, 과노출과 노출부족입니다.
과노출은 TV레인지 환경에서 오른쪽의 갈색 부분을 침범하는것을 말합니다. 저 갈색부분은 236~255인데,
235를 넘는 순간 넘은 부분은 다 흰색으로 화면에 나와버립니다. 즉 보여야 할것이 흰색으로 안보이게 된다는 말이죠.
반대로 0~15 부분도 마찬가지입니다. 16보다 어두워져 버리면 검정색으로 나와 아무것도 안보입니다.
동영상을 보정할때 이 레벨부분을 신경써줘야 합니다. 적당한 노출은 필요하나 너무 넘어버리면 곤란합니다.

장면에 따라 다르겠지만 보통 이정도 노출이 적당하다 할 수 있겠습니다. 관건은 peak 부분(오른쪽 제일 높은)이 갈색으로 넘어가지 않도록 하는 것입니다.

보통 밝은 흰색과 어두운 그림자가 공존하는 장면에선 어두운 부분 피크가 16언저리에, 밝은 부분 피크가 235언저리에 있을때 제일 다이나믹하고 생기있는 화면이 나오게 됩니다.




이제 직접 보정 예제 몇가지를 보여드리면서 설명드릴게요.

먼저 레벨 보정 예제입니다.
레벨 보정시 젤 중요한게 피사체 부분 광도가 16아래로 내려가거나 235위로 가버리지 않도록 해주시는 것입니다.(이것은 "손실"입니다.)
여기서 쓰일 필터는 SmoothAdjust.dll에 포함된 SmoothLevels입니다. 없으실경우 Levels(0, 1.000, 255, 0, 255) 쓰셔도 괜찮긴 합니다.


여기 굉장히 어두운 소스가 있습니다.

히스토그램을 보시면 어두운 부분이 잔뜩이고 밝은부분은 아주 조금 있네요. 근데 밝은 부분도 185 언저리에 있고 235와는 거리가 멉니다.
분명 저 흰 상의는 흰색입니다만 밝기가 흰색처럼 보이지 않네요.
이제 필터를 써서 흰색 부분을 밝게 만들어 주겠습니다.
SmoothLevels(input_low=18, gamma=1.00, input_high=190, output_low=16, output_high=235)
어두운 부분 18에서 16으로 2가량 내려서 약간의 빈틈을 없애구요 밝은부분 190에서 235로 늘려서 제대로 밝게 해줍니다.

그럼 이렇게 노출이 심하지 않고 적당한 밝기의 영상이 나오게 됩니다.
장면마다 조명이 다르기 때문에 SceneAdjust 같은 스크립트로 필요한 부분만 적용해 주시면 되겠습니다.
↑이처럼 어둠에 가라앉은 소스는 레벨을 끌어 올려주시면 되구요,


↓이처럼 밝아서 붕 떠있는 소스는 (축소해서 잘 안보이시겠지만 원본크기에선 붕 떠있는게 잘 보입니다.)

어둠으로 끌어 내려주시구요. 16아래로 갔는데 괜찮은 이유는요..

저부분이 관객석이기 때문입니다. 즉 레인지를 피사체에 맞출 필요가 있기 때문이죠.

당연히 관객석이 훨씬 어둡지만, 실제로 검정색에 가깝게 나와야 할것은 가인의 옷의 검은무늬입니다.
그래서 그러기 위해서 관객석을 그냥 검정색으로 손실시켜 버리는 겁니다. 관객 뒷머리숱 볼거 아니거든요.
여기까지가 레벨로 가라앉거나 떠있는 영상 보정하는법이었구요.





이제 색상 보정 알려드릴게요. SmoothTweak과 기본 필터인 RGBAdjust가  쓰입니다.

일단 색이 안맞는다는 것은 크게 색상을 끼얹었다거나 조명이 잘못됐다거나 색조가 안맞는 경우가 있습니다.
먼저 색상을 끼얹었을 경우인데요.


흔히 돌아다니는 이 색상 착시 사진을 보정해서 원래 색상으로 바꿔보겠습니다.

스크립트는 이러하구요. 과정 설명은 스크립트에 주석으로 달아놨습니다. 색상밝기를 낮춰주고 그 밝기를 다시 복구해주는게 포인트.
HD 소스라면 이런식으로 되겠네요.
ConvertToRGB(matrix="Rec709")
RGBAdjust(rb=-127.5)
ConvertToYV12(matrix="Rec709")
SmoothTweak(contrast=2)


결과




이번엔 잘못된 조명 받았을때~ 조명이 흰색일때 제대로 된 색상이 나온다고 생각하시면 쉽습니다. 감마와 색조 둘다 조정하는 방법입니다.
이를테면 흰색+파랑색 두가지 조명을 쐬이면 퍼렇고 이상한 화면이 나오겠지요. 그럼 파랑색 조명을 제거해 주면 됩니다.
조명은 감마값으로 표현이 되는데요, 파랑색 조명을 제거하고 싶은 경우 블루 감마를 줄여주면 됩니다.

원본 소스입니다. 분명 흰색 조명이 비춰지고 있는데 거기에 파랑색 조명이 추가가 되어서 이상한 색이 되버린 경우입니다.
흰색 조명과 파랑색 조명이 천장에서 비춰지고 있는걸 동영상에서 목격했기 때문에 자신있게 파랑색 조명을 제거해주겠습니다.
ConvertToRGB(matrix="Rec709")
RGBAdjust(bg=.68)#블루 감마를 1에서 0.68로 줄여줬습니다.
ConvertToYV12(matrix="Rec709")

여기서 블루감마를 얼마나 줄여주나에서 눈썰미가 필요합니다. 지금 이 파란게 조명때문인지 색조때문인지 판단하기가 힘들거든요..
저는 0.68정도까지만 조명이라고 생각해서 0.68에서 멈췄습니다. 값을 조금씩 비교해가면서 찾아야해요.
여기서부턴 색조의 문제라고 판단을 내렸으니 색조를 고쳐주도록 하겠습니다.
SmoothTweak(hue1=-15, hue2=3)
hue1은 Cb고 hue2는 Cr입니다. 히스토그램 두번째와 세번째에 해당합니다.

제가 생각하는 올바른 색상으로 조절하였습니다. 색온도를 높지도 낮지도 않게 적당히 맞추면서 색상이 산으로 가지 않게 하는게 포인트.
Cb를 낮출수록 Cr을 높힐수록 색온도가 올라갑니다.

마지막으로 레벨까지 적절히 맞추면서 마무리.
SmoothLevels(input_low=21, gamma=1.00, input_high=220, output_low=16, output_high=235)




마지막 궁극의 노답소스.

조명도 개판이고 흰색 조명도 없고 색조도 개판.. 이럴때 전 그냥 반쯤 포기하고 시작합니다..
일단 영상이 완전 붉어요.. Cr을 -10 해줍니다. 그리고 영상이 너무 누래요. Cb를 +40해줍니다. 피부색을 피부색 답게 만드는거에 초점을 뒀습니다.
SmoothTweak(hue1=40, hue2=-10)

이제 피부가 최소한 살색같아 보이네요.
(어느정도 선까지 조정하느냐는 감이 필요합니다. 색조로만 보정하시려고 하시면 안돼요.)
근데 전체적으로 퍼렇게 붕 떴어요. 블루감마네요.(아마도..)
블루감마를 0.6으로 줄여줍니다.
ConvertToRGB(matrix="rec709").RGBAdjust(bg=.6).ConvertToYV12(matrix="Rec709")

최소한 봐줄만 하다는거에 만족하며 턴을 마치겠습니다..
제 실력으론 여기서 보정이 더는 안되더라구요.. 마무리 레벨조절은 위에서 실컷 했으니 생략..



제가 보정하는 과정은 대충 이렇습니다. 어디서 배운게 아니라 서두에 쓴 정보도 맞는지 모르겠고
보정도 이렇게 하는게 좋다고 장담은 못하겠는데 궁금해하시는 분들이 계셔서..

3줄 요약.
1.SmoothLevels() 레벨변경
2.SmoothTweak() 색조변경
3.RGBAdjust() 색비율변경


추가로.. 보정이 필요해 보이는 경우 아니면 왠만하면 원작자의 의도를 존중해줍시다.(뮤비같은 이미 보정된 영상)


그리고 레벨이든 색조든 그 영상을 오래 보고 있으면 눈이 적응해서 올바른 색상을 보게됩니다.(혹은 틀림을 모르게 된다 라고 표현할게요)

이게 맞는 레벨이나 색이라고 판단해버리니 너무 오래 보고 있지는 마세요.


+아 그리고 또 추가로 광도의 비율을 바꾸는 Curve도 보정에 중요한 기술중 하나인데 이건.. 대충 개념은 아는데 쓸줄을 몰라서..