안녕하세요? 맨날맑음입니다.

화살표를 그려야 할 일이 생겨서 어떻게 그릴까 생각하다가, Line을 여러개 그려서 화살표를 만들려고 했습니다.
선의 각도에 따라 화살표 머리 부분의 각도가 변하기 때문에 수학을 못하는 저로써는 화살표 그리는 것 조차도 힘든일이 었습니다.

하지만! .NET의 Pen 클래스는 Line의 끝점들의 모양을 변경시켜 주는 기능을 제공합니다.
Pen 클래스의 좀더 자세한 설명은 아래의 MSDN 도움말을 참조 하시면 됩니다.
http://msdn.microsoft.com/ko-kr/library/system.drawing.pen(en-us,VS.85).aspx

MSDN에서 Pen 클래스의 속성을 보면 StartCap 과 EndCap이 있습니다. 이것이 선의 끝모양을 지정하는 속성입니다. 그럼 선의 시작과 끝 모양을 화살표로 바꾸어 보겠습니다.

Pen pen = new Pen(Color.Blue, 6);
pen.StartCap = LineCap.ArrowAnchor;
pen.EndCap = LineCap.ArrowAnchor;
위의 소스에서 처럼 Pen 객체를 생성하고, 해당하는Cap 속성을 바꿔주는 아주 간단한 방법으로 끝모양을 바꿔줄 수 있습니다.  LineCap 사용을 위해서는 using System.Drawing.Drawing2D;을 해주셔야 합니다.
화살표 모양 이외에도 여러 모양을 지정 할 수 있습니다. LineCap 을 살펴 보면 열거형으로 되어 있습니다. 각각의 멤버의 의미를 보면 다음과 같습니다.
Flat : 일직선 형태의 끝 모양을 지정합니다.
Square : 정사각형 형태의 선 끝 모양을 지정합니다.
Round : 둥근 선 끝 모양을 지정합니다.
Triangle : 삼각형 선 끝 모양을 지정합니다.
NoAnchor : 앵커를 지정하지 않습니다.
SquareAnchor : 정사각형 앵커 선 끝 모양을 지정합니다.
RoundAnchor : 둥근 앵커 끝 모양을 지정합니다.
DiamondAnchor : 다이아몬드 앵커 끝 모양을 지정합니다.

ArrowAnchor : 화살표 모양의 앵커를 지정합니다.
Custom : 사용자 지정 선 끝 모양을 지정합니다.

AnchorMask : 선 끝 모양이 앵커 모양인지 여부를 검사하는 데 사용되는 마스크를 지정합니다.
아래와 같이 간단하게 Windows Form 프로젝트를 생성해서 Paint 이벤트 핸들러에서 화살표를 그려 보겠습니다.

using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.Paint += new PaintEventHandler(Form1_Paint);
        }

        void Form1_Paint(object sender, PaintEventArgs e)
        {
            Pen pen = new Pen(Color.Blue, 6); //Pen 객체 생성
            pen.StartCap = LineCap.ArrowAnchor; //Line의 시작점 모양 변경
            pen.EndCap = LineCap.ArrowAnchor; //Line의 끝점 모양 변경
            e.Graphics.DrawLine(pen, 20, 50, 300,50); //Line 그리기
        }
    }
}
 
이와같이 복잡한 화살표 알고리즘 없이 Pen 클래스의 속성 변경 만으로도 간단하게 화살표를 그릴 수 있습니다.
참 쉽죠잉~
Posted by 맨날맑음


안녕하세요? 맨날맑음 입니다.

나름 개발자 기술 블로그에 이런 글은 어울리지 않을 수도 있지만, 이번 사건을 보면서 느낀점을 써볼까 합니다.

(그림1. 출처 : http://blog.naver.com/gksksla2761?Redirect=Log&logNo=100075692226 )


요즘 연예계 가장 큰 이슈 중 하나는 잘나가는 2PM이라는 아이돌 그룹의 멤버인 재범의 한국 비하와 그로인한 탈퇴 / 미국행입니다. 저는 26살 먹은 남자로 2PM의 팬도 아니고, 2PM이란 그룹은 알고 있지만 박재범이라는 이름까지는 알지 못하는 그런 평범한 학생입니다. 물론 소녀시대나, 원더걸스 같은 여성 그룹의 재롱이 더 좋아질 나이라고 생각합니다.


언제나처럼 네이버 메인기사를 훝어보다가 '재범 한국 비하'라는 언론들의 기사를 보았습니다.

 

2PM 재범 한국 비하 발언 파문 "나는 한국이 싫다"
“2PM 재범, 양키 고 홈”… 가요 팬들 ‘한국 비하’에 뿔났다
2PM 재범, "한국 역겹다" 비하발언 공식 사과


제목만 보아도 굉장히 '강한 표현'을 사용해서 연예계 기사는 관심 없는 저도 클릭해 보게 만들었습니다.


이 기사들을 보면서 저는 박재범이 나쁘구나 생각했습니다.

대부분이 박재범은 한국에 대해 모욕적인 발언을 했고, 한국을 비하했다는 내용의 보도 였습니다. 그 내용들이 사실이기도 했습니다.(물론 해석의 차이에서 생기는 것 일수도..)


박재범군이 연습생 시절(어린나이의)에 자신의 미래에 대한 불안과, 문화의 차이에 대한 불안이 대부분 이었습니다. 이 시점에 지인으로 부터 온 '재범이 불쌍해..'라는 문자에 저는 '그놈은 한국을 무시했어'라고 응답할 만큼 반감을 가지게 되었습니다.


한편으론 4년전.. 미래가 불확실 할때 저지른 행동이 이런 파장을 일으킨대 대한 동정심도 있었습니다. 일반인이라면 누구나 할 수 있는 '대한민국에 대한 비평'을 우리가 과민 반응한다는 생각도 했습니다.

그러면서 네티즌들의 일반적인 반응이었던(2PM 팬들을 제외) '2PM에서 탈퇴해라.', '양키는 미국으로 돌아가라' 라는 반응은 좀 너무하다고 생각했습니다.


재범은 당시 어린나이였고, 누구나 이런 생각을 할 수 있다고 생각했습니다.
현재.. 재범이 2PM을 탈퇴하고, 미국으로 돌아간 시점에 올라온 기사를 보면 어처구니가 없습니다.
대부분의 기사는 네티즌의 마녀사냥으로 재범이 2PM을 탈퇴하고 미국으로 갔다는 기사였습니다. 재범을 동정하는 기사지요..
'2PM' 탈퇴 박재범, 시애틀 공항 도착해 어머니 안고 '눈물'
스물 둘 재범의 선택, 남은건 눈물과 ‘돌아오라’는 팬들의 메아리 뿐
2PM 재범, 어머니 품에 안겨 ‘오열’ 팬들은 구명운동 나서

 이 기사를 보면서 저는 재범이 불쌍하다고 느꼈습니다. 제가 문제라고 생각한것은 이것입니다. 대부분의 네티즌은 기사를 믿을 수 밖에 없습니다.


지금 현실을 보면 재범이 네티즌의 마녀사냥의 희생양이고, 네티즌이 재범을 2PM에서 탈퇴 시키고, 미국으로 가게 만들었다는 뉘양스로 쓰여 있는게 사실입니다.
제가 강조하고 싶은 부분은 언론이 사람들을 선동했다는 것입니다. 2PM에 별 관심이 없는 저 조차 이렇게 느끼게 되는데, 다른 사람들도 저와 같은 생각일 것이라는 것입니다.

나쁜놈이라고 보도하던 기사들이 재범이 미국으로 돌아 간 후 부터는 네티즌이 그렇게 만들었다고 선동하고 있습니다. 과연, 언론의 이런 자극적인 제목의 기사가 없었다면 이렇게 까지 생각하게 됬을까요?

물론 저만 이런 생각이 들 수 도 있습니다. 허나 저는 이번 사태는 앞다투어 자극적인 제목으로 가쉽거리를 만들어낸 언론의 힘도 무시 할 수 없다는 겁니다. 세상..참 무섭습니다. 어떤 기사에는 '파시즘'을 들먹이며, 군중심리에 대해 표현하고 있더군요.. 과연 이런 군중 심리를 일으킨 주범은 누구일지.. 생각하게 되는 사건입니다.


ps.. 글을 쓰던 도중 술자리가 생겨, 조금 횡설 수설하게 된 면이 있군요.. 제가 강조하고 싶은 것은 지금의 사건을 군중심리, 네티즌 때문이라 보도하는 언론이 자신들의 보도 때문이라는 생각은 하지 않는 데 있습니다. 초기 기사엔 재범이 나쁘다는 것만 강조해온 언론이 이제는 네티즌의 속칭 '마녀사냥 ' 때문에 이런일이 일어났다고 보도한다는 거지요..

좀 더 생각해봐야 할 일인것 같습니다. 안타깝네요. 한국을 욕했다고 배척하기 보단.. 그걸 고칠 수 있도록 포용하는 방법도 좋은 생각이라는 생각이 듭니다.

Posted by 맨날맑음
TAG 2pm, 재범

#1. [H.264] 동영상 압축의 기본 개념
#2. [H.264] 동영상 압축의 기본 개념 – RGB, YCbCr, 서브샘플링
#3. [H.264] Block-based Motion Estimation(ME)
#4. [H.264] Discrete Cosine Transform(DCT) 이산 코사인 변환
#5. [H.264] Quantization(양자화)과 Zig-zag scanning

안녕하세요? 맨날맑음 입니다.


이전 포스팅에서 동영상을 압축하기 위한 프로세싱 과정중 ME(Motion Estimation)에 관해 알아 보았습니다. 이번에는 DCT(Discrete Cosine Transform)에 관해 알아보도록 하겠습니다.


#1. Discrete Cosine Transform 개요

Discrete Cosine Transform(이하 DCT)는 무엇일까요? 번역해 보자면 이산 코사인 변환이라고 합니다. 이전 시간에 배운 ME는 프레임간 유사성을 이용하여 영상을 압축 할 수 있는 기법이었는데요. DCT는 해당하는 프레임(Picture)만을 이용해서 영상을 압축 할 수 있도록 하는 기법이라 할 수 있습니다. 그렇기 때문에 사진을 압축하는 JPEG에서 쓰이는 방식입니다. 동영상 코덱에서는 H.261, H.263, H.264.. MPEG등 에서 이 방식을 사용하여 영상을 압축하게 됩니다.


대체 DCT란 놈이 어떤 것인지 좀더 자세히 알아보도록 하죠. 혹시 신호처리를 알고 계신 분은 좀더 쉬울 수 있겠습니다. 저는 신호처리를 모르는 관계로 처음 배울 때 잘 이해가 가지 않더군요.



- Fig1. DCT 변환 -


영상을 DCT 변환하면 Fig1에서 처럼 공간 영역(Spatial Domain)에서 주파수 영역(Frequency Domain)으로 변하게 됩니다. 그림을 잘 살펴보면 주파수가 낮은 쪽으로 데이터(신호)가 몰려 있는 것을 볼 수 있습니다. 이와 같이 DCT를 하면 신호성분이 낮은 주파수에 몰리게 되는 ‘에너지 집중 현상’이 나타납니다.

 

 

#2. DCT를 하는 이유


- Fig2. DCT Coefiicients -

 

그럼 코덱은 압축을 위해서 왜 DCT를 수행 하는 것일까요? DCT는 공강영역을 주파수 영역으로 변환한다고 하였습니다. 영상을 관찰하다 보면 인접한 픽셀간에는 비슷한 색상인 경우가 많이 있습니다. 즉 8×8 블럭을 DCT하였을 경우 64개의 픽셀중에 같은 색상이 낮은 주파수(DC)로 몰리게 됩니다. 그리고 색상의 변화가 있는 경우 높은 주파수(AC)으로 위치하게 됩니다.

 

DCT를 수행하게 되면 대부분의 이미지는 Fig1에서 와 같은 결과가 나오게 됩니다. 빨간색으로 우뚝 솟은 부분(DC)이 제일 큰 신호 값이며, 파란색은 울퉁불퉁 하긴 하지만 높은 주파수 영역으로 갈 수록 평평한 것을 볼 수 있습니다. 즉 위에서 설명 했듯이 8×8 블럭의 색상 평균값이 DC성분이 되며, 나머지 평균값과 틀린 부분이 AC 성분이 되는 것입니다. 눈으로 보아도 DC에 값이 많이 몰린 것을 알 수 있죠? 이 의미가 바로 인접한 픽셀간은 거의 비슷한 색상으로 이루어 져 있기 때문에 DC의 값이 크다라고 생각하시면 됩니다.

그런데 사람의 눈 또한 낮은 주파수 성분(DC)에는 민감하게 반응 하지만, 높은 주파수 성분(AC)에는 민감하지 않기 때문에 높은 주파수 영역(그림에서 파란색)을 좀 생략 한다고 해도 화질의 차이를 잘 느끼지 못하게 됩니다. 이것이 압축이 되는 원리 입니다.


그림1 에서 보는 것과 같이 DCT변환 전에는 8×8 블럭 이므로 64개의 데이터가 필요 하지만  DCT를 하여 높은 주파수 성분(AC)을 좀 버려서(화질의 차이는 크지 않으므로)  DC에서 가까운 10개의 데이터만 가지게 된다면, 그만큼 압축이 되는 것 입니다. 사실 DCT는 이렇게 주파수 성분으로 바꾸는 작업만을 이야기 하며 다음시간에 이야기할 Quantization과 Entropy coding과정을 거쳐야 실질적인 압축이 일어납니다.



#3. Discrete Cosine Transform(DCT)

위의 개념이 이해가 가시나요? 어떻게 영상을 주파수 영역으로 변환하는지에 관해 알아 보겠습니다.


DCT도 ME와 마찬가지로 블럭 단위로 수행하게 됩니다. 그 이유는 블럭 사이즈가 커지면 시간이 엄청 걸리기도 하지만, 전체 프레임을 한번에 처리하기 위해서는 어마어마한 메모리도 필요 하게 됩니다. 그래서 일반적으로 JPEG, H.261, H.263, MPEG에서는 8×8 블럭 단위로 DCT를 수행하게 됩니다. (H.264는 기본 4×4에 변형이 가능합니다.)


그럼 어떻게 공간 영역을 주파수 영역으로 바꿀 수 있을까요?

아래는 2D-DCT를 수행하기 위한 수식입니다.


- Fig3. 2D-DCT -

V는 DCT를 수행하여 주파수 도메인으로 바뀐 , C는 DCT수행에 필요한 메트릭스(Fig4 참조), X는 원본 블럭, CT는 C 메트릭스의 가로 세로를 변환한 메트릭스 입니다.

 


- Fig4. N×N Cosine Transfrom Matrix   C={c(k,n))} -

 

Fig4는 DCT 수행에 필요한 Matrix를 어떻게 생성하는지를 나타냅니다. k는 행을 n은 열을 나타내고 N은 Matrix의 크기를 나타냅니다. 우리는 8×8 DCT를 수행할 것이므로 N은 8이 됩니다. 이렇게 생성된 Matrix를 이용하여 V=CXCT 라는 수식으로 DCT가 된 데이터를 가져올 수 있습니다. 아래 Fig5는 DCT후의 데이터 변화를 나타냅니다. 숫자로 확인하여도 DC성분에 값이 집중된 것을 알 수 있습니다.

 


- Fig5. DCT후의 데이터 변화 -

 

아래에 있는 Fig6에서도 마찬가지로 높은 값들은 DC쪽에 집중되어 분포하게 되는 것을 알 수 있습니다.

 
-Fig6. Matlab으로 확인해본 DCT후의 데이터 분포-

 

 

 

#4. Inverse DCT는 어떻게?

DCT를 하여 주파수 도메인으로 변환 할 수 있다는 것을 알았습니다. 그럼 다시 공간 도메인으로 변경 하려면 어떻게 해야 할까요?


- Fig7. 2D-Inverse DCT -

위와 같은 공식으로 원래 블럭을 복원 해 낼 수 있습니다. 물론 복원한 블럭은 오리지날과 100% 동일하게 됩니다.

 

#5. 끝마치며

이번 시간에는 코덱의 인코딩 과정중 하나인 DCT의 개념과 DCT를 왜 해야하는지 알아 보았으며, DCT된 블럭을 원래대로 되돌리는 것 까지 알아 보았습니다. 다음 시간에는 Quantization에 관해 알아보고 전체적인 인코딩 프로세싱도 살짝 짚어 보려구 합니다.

제가 전체 그림을 제시하고 세부 강좌를 만들었어야 하는데, 세부적인 설명부터 하다보니 좀 오해가 생기는 부분이 있는 것 같아서요. 그럼 좋은 주말 저녁 되세요^^

Posted by 맨날맑음

안녕하세요? 맨날맑음 입니다.

예전부터 하려고 했지만 약해빠진 의지로 인해 못하고 있던 금연을 하려고 합니다. 휴가도 다녀왔고 가장 스트레스가 없는 방학기간이며(일주일 남았지만) 요즘 들어 '급' 안좋아진 몸을 보며 이번엔 꼭 금연을 해야 겠습니다. 

이런 쓸때없는 글을 올리는 이유는 금연 수칙 첫번째인 '나의 금연 사실을 모두에게 알려라!'를 실천하기 위한 것입니다. 오늘 영결식을 하는 故 김대중 대통령님 또한 하루 3갑을 피는 '골초' 였지만 금연을 하신것 처럼 저도 이번에야 말로 꼭 금연을 하고야 말아야 겠습니다.(금단현상으로 이상한 말을 하는군요'')

벌써 9년째 거의 매일 한갑씩 피웠는데.. 잘 할 수 있겠죠? ㅠ

의지가 약해질 때 마다 보려고 금연을 하는 이유도 좀 써봅니다.
#1. 담배를 피울 때 마다드는 자괴감을 없앨 수 있다.
#2. 요즘 들어 부쩍 나빠진 몸 상태가 걱정된다.
#3. 하루 2,500원이면, 10일이면 25,000원 100일이면 250,000원 Olleh!!
#4. 아침마다 상쾌하게 일어나서 하루를 시작 할 수 있다.
#5. 어무니께 냄새난다고 구박 받는 일도 이젠 안녕~

이번엔 꼭 성공 할 수 있겠죠!! 아자아자 화이팅! 난 할 수 있다.
따스한 200원짜리 밀크커피와 담배는 이제 안녕~~(더불어 하루 4-5잔 먹던 커피도 끊을 수 있겠군요..)
이것은 1석 2조, 꿩먹고 알먹고, 도랑치고 가재잡고!!

나는 비흡연자..원래부터 담배 따윈 몰랐던 비흡연자.. (자기 최면중ㅠㅠ)
Posted by 맨날맑음
TAG 금연

#1. [H.264] 동영상 압축의 기본 개념
#2. [H.264] 동영상 압축의 기본 개념 – RGB, YCbCr, 서브샘플링
#3. [H.264] Block-based Motion Estimation(ME)
#4. [H.264] Discrete Cosine Transform(DCT) 이산 코사인 변환
#5. [H.264] Quantization(양자화)과 Zig-zag scanning

안녕하세요? 맨날맑음 입니다.

가장 덥다는 말복이 바로 어제 였습니다. 다들 ‘삼계탕’은 맛있게 드셨는지 모르겠네요; 저는 이마트의 닭이 매진되어 삼계탕은 못 먹고 말았네요 ㅠ_ㅠ 그 큰 마트에서 매진이라니..말복 때 죽음을 맞이한 수많은 닭들에게 감사할 때 입니다;

이번 포스팅에서는 동영상 압축의 핵심이라 할 수 있는 Block-based Motion Estimation(이하 ME)에 관해 알아 보려고 합니다.

본 내용으로 들어가기 전에 ME에 관해 간단히 소개하자면, 지난 시간에 프레임과 그 인접한 프레임은 거의 비슷한 형태로 이루어 져 있다고 하였습니다. 만약 프레임1과 프레임2가 있을 때 프레임2는 1과 거의 비슷하기 때문에 굳이 모든 데이터를 가지고 있을 필요 없이, 1의 어느 부분과 비슷하다..라고 표시만 해주는 방법으로 데이터의 양을 줄이게 됩니다. 이렇게 하기 위해서 ME를 하여, 프레임1(Reference Frame) 에서 어느 부분과 가장 일치하는지 찾아주는 과정이라고 할 수 있습니다. 아래에서 자세히 알아보도록 하죠.

#1. Block-based?

위에서 Block-based Motion Estimation라고 했습니다. 굳이 번역하자면 블럭 기반의 움직임 추정(?)이라고 하면 될 것 같습니다. 그럼 블럭 기반이라는 말부터 살펴 보면 ME를 할때 프레임 전체를 한번에 하는 것이 아니라 하나의 프레임을 잘게 잘라(8×8, 16×16 or 32×32) 사용하게 됩니다. 기본적으로는 16×16의 매크로 블럭(Macro-Block)을 사용하게 됩니다.


-그림1. 16×16 Macro Block으로 나눈 모습-

#2. Motion Estimation



-그림2. Motion Estimation 개념도-

그림 2가 이해 가시나요?  Frame(t)(현재 프레임)에서 3번째 매크로 블럭을 처리하고 있다고 가정 합니다. Frame(t-1)(이전 프레임)에서 매크로 블럭과 가장 비슷한 곳을 찾는 모습이죠. 저 빨간색 사각형은 Frame(t-1)에서 비슷한 곳을 찾을 Search Range(검색 범위) 입니다. 눈으로 보아도 분홍색 화살표가 가르키고 있는곳이 현재 매크로 블럭과 많이 일치하는 것을 알 수 있습니다. Search Range는 임의로 정할 수 있지만 일반적으로 Block Size의 ±7을 사용하게 됩니다.

그럼 그림처럼 현재 매크로 블럭이 이전 프레임과 가장 일치하는 최고의 매칭 포인트를 어떻게 찾게 되는지 매우 궁금 해 집니다. 비밀은 바로 SAD 방정식에 있습니다. SAD 방정식을 사용하여 최고의 매칭 포인트를 찾아 내는 것이지요.


-그림3 SAD equation-

수식을 보니 갑자기 머리가 아파옵니다. 저 같이 수식 알러지가 있으신 분들을 위해 친절하게 그림으로 설명해 드리죠.갑자기 제가 친절한 금자씨(?)라도 된 것 같습니다;



 -그림4. Motion Estimation 과정(1)-

그림 4를 보면서 설명 하겠습니다. 이 그림은 이전 프레임(frame t-1)을 나타냅니다. 사각형 하나는 하나의 픽셀입니다. 빨간색 사각형으로 Search Range(검색 영역)가 있습니다. Cerrent block이 바로 현재 프레임의 매크로 블럭입니다. (원래 16x16으로 해야 하지만 그림 그리는 것도 만만치 않습니다)



 -그림5. Motion Estimation 과정(2)-


그림 5에서 보는 것 처럼 Search Range를 매크로 블럭으로 탐색 하면서 Frame(t-1) - Cerrent block 를 계산하여 그 ‘절대값’을 Origin에 저장하게 됩니다.



 -그림6. Motion Estimation 과정(3)-


이렇게 계산된 값들 중 그림 6에서 처럼 가장 작은 값을 찾는 것이죠. 숫자 22가 들어있는 좌표(6.5)가 최소값을 갖는 바로 Current Block과 가장 일치하는 이전 프레임의 좌표인 것입니다. 이 지점을 Motion Vector라고 합니다. 즉 이전 프레임에서 현재 블럭과 가장 일치하는 지점을 말합니다.



-그림7. Motion Vector-


이렇게 Search Range의 모든 좌표를 전부 검색하는 방법을 Full Search라고 합니다. 이러한 ME의 과정은 코덱이 영상을 압축하는 과정에서 많은 비트 수를 감소 시켜 주게 됩니다.  그림7의 단순한 프레임과의 차이와 ME를 사용한 차이를 보시면 확연하게 그 차이를 알 수 있습니다.(흰색이 데이터가 있는 부분입니다) ME를 했을 경우는 잔여 데이터가 거의 없는 것을 볼 수 있습니다.



-그림8. 단순한 프레임간의 차와 ME를 수행 했을 때의 차이-

 

그런데 ME는 전체 인코딩 과정중에 가장 많은 부하(?)를 일으킵니다. ME를 통해 데이터의 양은 많이 감소하게 되지만 Search를 하는 계산 과정이 있기 때문에 속도는 많이 떨어지게 되는 것이죠. 실제 H.264에서는 Full Search외에 여러 가지 Search 방법(예. 다이아몬드 서치)을 통해 속도 향상을 할 수 있도록 하고 있습니다.(이런 방법들은 차차 소개하도록 하겠습니다)

글이 많이 길어지는군요.. ME를 간단하게 요약 해 보자면.
  • 현재 프레임(t)의 처리 할 매크로 블락을 만든다.
  • 이전 프레임(t-1)에 Search Range를 설정한다.
  • Search Range를 SAD 방정식으로 Search 하여 그 결과 값을 저장한다.
  • 결과값 중에 가장 작은 값(Motion Vector)을 찾는다.
  • Moton Vector의 매크로 블럭과 현재 매크로 블럭의 차이의 절대값을 결과(Residual) 데이터에 저장한다. 


#3. 디코더(Decoder)의 데이터 복구

지금까지 인코더(Encoder) 측에서 ME를 통해 데이터를 줄이는 방법을 상세하게 설명 했습니다. 그렇다면 디코더에서는 어떻게 Residual 데이터를 가지고 원본 데이터를 복원해 나갈까요?


-그림9. 디코더는 어떻게 원본 이미지를 복원 할 수 있을까?-


정답은 ME의 과정을 반대로 수행 하면 될 것입니다. 디코더 또한 현재 프레임을 되 살릴 때 매크로 블럭 단위로 복원하게 됩니다. 그렇다면 디코더가 매크로 블럭을 복원하기 위해 가지고 있는 데이터는 무엇이 있을까요? 디코더는 바로 이전에 처리한 이전 프레임의 원본 이미지(사실 조금의 손실이 있는..)와 현재 프레임의 Residual 데이터를 가지고 있을 것 입니다. 이 두 가지를 가지고 현재 복원 할 매크로 블럭의 Residual 데이터와 이 Residual 데이터가 이전 프레임의 어디에 위치하였는지(Motion Vector)정보를 이용하여 둘을 합하여 현재 블럭을 복원 하는 것입니다. 그림 10과 같이 이러한 방법을 반복하여, 프레임 전체를 복원 하게 됩니다.



-그림10. 디코더의 이미지 복원 과정-
 


#4 . 실습

ME의 과정이 이해 가시나요? 설명 만으로는 100% 자신의 것으로 만들기 어렵습니다. C나 C++을 이용하여 프로그램을 만들어 보면 확실하게 이해가 될 것 입니다.

준비물.

  • 각자 익숙한 개발 툴(저는 Visual Studio 2008)
  • 실습에 필요한 YUV 파일 Download(http://trace.eas.asu.edu/yuv/)
    - 저는 football_sif.yuv 사용
  • 결과를 확인하기 위한 YUV 플레이어
    - 이 플레이어를 열고 마우스 오른쪽 버튼을 누른 후 셋팅에서 화면의 해상도와 Color 타입을 조정하여 사용하면 됩니다.

 

준비가 되었으면, ME를 작성 해 보시면 됩니다. 그런데 가장자리를 Search 하기 위해서는 Search Range가 –인덱스가 나오는 경우가 발생 하므로, 저는 학습의 편의상 동영상의 가장자리 16은 ME의 대상에서 제외 하도록 하였습니다.


아래에 제가 만들어본 프로그램을 올려 놓지만, 꼭 자신이 만들어 보아야 자신의 것이 됩니다.

프로그램을 컴파일 한 후, Debug 폴더안의 실행파일을 실행 시켜 ME를 수행 할 수 있으며, 결과는 Root 폴더의 Me_sample에서 residual.foo 파일을 열어 보면 확인 가능 합니다



#. 마치면서

이번 포스트에서는 동영상 압축의 핵심인 ME에 대한 자세한 소개와 디코더 쪽에서 데이터를 복원하는 방법을 알아 보았습니다. 다음번에는 DCT를 이용하여 데이터의 비트 수를 줄이는 방법에 대해 자세히 알아 보겠습니다.

Posted by 맨날맑음