• 번호 425705 | 2008.12.02 IP 121.170.***.139
  • 조회 505 주소복사

이 글을 보시는 분들 중 경제 및 경영학과를 졸업하신 분들은 읽지 마세요..

->미천한 지식이라 쪽팔려요.
고등학교 이 후 경제에 관하여 체계적인 공부를 하시지 못하시거나. 문과 및 이공계통을 졸업하신

분들에게는 다소 도움이 되리라 생각되면서 저와 비슷한 지식수준을 가지고 계신분들에겐 많은 도움이되리라 생각되어집니다. 바카(바그다드카페)의 기초경제 1강을 시작합니다.

이번 1강은 다음과 같은 순서로 진행합니다.

 

경기변동 개념 및 측정->경기변동 원인 및 특징->경기변동이론 및 경기정책->마지막으로 경기예

측분석방법으로 진행하겠습니다.

 

이 내용은 고졸학력이상자들 이라면 누구나 알기쉽게 최소한 풀어서 설명을 하니 그러한 분들에겐 상당한 도움이 되리라 생각합니다.

오늘은 경기변동 개념 및 측정에 관하여 썰을 풀어볼까 합니다.
우선 경기가 무엇인가? 이론적 정의는 "국민경제의 총체적 활동수준"이라고 하는데 쉽게 말해서
먹고살려고 하는 모든 행위를 말하는 것이죠..경기는 기본적으로 성장순환(Growth Cycle)을 합니

다.
특히나 선진국이 아닌 개도국(개발도상국)의 경우는 대부분이 성장순환을 합니다.인구증가,기술개

발,자본축적과 같은 요인들로 말이죠.하지만 상승곡선이 직선비례하지않죠
불규칙적이며 비대칭적으로 Cycle을 형성하며 성장하죠..그래서 우리들은 고딩때 배웠죠.경기순환
은 회복기->성장기->후퇴기->침체기 이렇게 말이죠 요즘은 이렇게 하지 않고 확장기 및 수축기
단 2개의 이분법으로 분류합니다.이유는 회복기와 성장기 또 후퇴기와 침체기를 구분하기가 애매하다고 합니다. 경기 불황의 끝을 저점(Trough) 경기호황의 끝점을 정점(Peak), 저점과 저점을 순

환주기(Cycle), 저점과 정점의 수직을 진폭(amplitude)라고 합니다. 모 그렇다구여..그럼 저점과 정점을 어디서 누가 판단할까요? 주로 한국은행 및 통계청에서 일정부분 전문가에게 의뢰해 동의를 구한 후 저점일과 정점일을 정합니다. 저점일과 정점일은 기준순환일(reference date)이라고 합니다.
참고하시구요.->추후 이 내용에 대한 도표 및 그림들을 제 블로그에 올려놓겠습니다.

 

우리나라는 현재 약 7순환정도 하는 되요..2004년 정점으로 현재 2008년 아직 저점을 정하지 못하고 있습니다.사견으로는 2009년 2사분기 정도에 저점을 예상합니다만..모르죠 어케될지..우쨋든.
이러한 경기변동에 대하여 3가지 구분이 있는데요. 아래와 같습니다.
장기파동 : 기간- 50년, 원인-신기술및 자원개발, 발견자 - 콘트라 디에프
중기파동 : 기간- 10년, 원인-소규모기술개발 및 설비투자내용연수, 발견자-주글라
단기파동 : 기간- 2~6년,원인-통화정책에 따른 물가 및 금리 변동,생산제고품변화, 발견자-키친

여기서 설비투자내용연수는 공장기계바꾸는데 대체로 10년주기라고 하네요, 2차대전 이후 전세
계는 단기파동의 중요성을 인식하고 단기파동에 대한 연구만을 한다고 합니다.

 

자 이제 경기변동을 측정하는 수단으로 거시경제지표가 있지요..함 봐볼까요.
우선 다음과 같은 요소들이 있습니다.


1.실물경제지표:GDP(국내총생산),BOP(국제수지)
2.물가지수:CPI(소비자물가지수),PPI(생산자물가지수),GDP 디플레이터(물가상승압력지수)
3.통화량
4.통화유통속도
5.금리

 

자 그럼 위 내용들이 무엇을 말하는지 하나하나 볼까요.
우선 GDP부터요..예전에 우리 영삼이 엉아가 세계화 세계화 부르짖기 직전엔 GNP(국민총생산)이
중요했는데요.OECD 가입 이후 GDP를실물경제지표로 삼게되었지요.GDP는 한국인이든 외국인이든 누구든 한국이란 땅에서 생산한모든 것의 총합이지요.즉 지역(영토)개념이 있습니다.
또한 부가가치만 합산합니다.예를 들어자동차 한대의 가격이 2천만원이면 부품값 1천만원을 제하고 나머지 1천만원만 합산하지요.
그리고 시장가격이 되어있는 것들만 합산합니다. 예를 들어 주부들의 가사노동은 시장가격
형성이 안되어 있지요 만약 주부들의 가사노동을 합산한다면 우리나라는 GDP대비 세계 4위
정도의 경제대국이 되지요.ㅋㅋㅋ 2007년도 우리나라의 GDP는 840조정도됩니다. 세계 12위
브라질 다음이지요. 올해는 얼마나 했을려나 걱정걱정 여기서 한 2%정도 올랐으려나...
어쨋든 계속 씨부려야징..GDP는 명목GDP(당해년도)와 실질GDP(기준년도)->울나라 대걔
5년단위로 함, 요렇게 구분하구요..이렇게 구분한 이유는 물가상승 즉 인플레이션 측정을
하기 위해 그렇게 합니다. 아래에 GDP디플레이터를 설명하면서 그 이유를 알려드리지요.
뉴스나 신문에서 보면 내년 경제성장률 2%, 4% 씨부리지요..요것이 바꿔말하면 실질GDP
성장률과 같다고 보시면 됩니다. 즉 경제성장률=실질GDP
원화를 환산한다는거 잊지마세용.

 

두번째 BOP(Balance of Payment) 즉 국제수지요.국제수지는 울나라하고 딴 나라넘들하고
거래한 모든 것 즉 달라로 환산한다는 사실.
국제수지의 구성은 다음과 같지요-> (경상수지+자본수지+준비자산증감=외환보유액)
경상수지는 또 다음과 같지요(상품수지+서비스수지+소득수지+경상이전수지)로요
자본수지는 다음과 같지요(투자수지+기타자본수지) 요렇게요.
그럼 좀 볼까요 상품수지는 수출과 관련된 품목입니다. 서비스수지는 운수,여행,보험,기타등등
소득수지는 임금 및 투자소득, 경상이전수지는 해외송금 등을 말하지요.
증시에 외국인의 매수세가 증가했다면 자본수지 즉 투자수지를 말하구요
해외이주시 비용은 기타자본수지에 속합니다.이상이에요

 

세번째 CPI(Consumer Price Index)소비자 물가지수는 서울을 포함한 전국 40여개 도시의
가계지출중 비중이 1/10000에 해당하는 품목 500여개를 조사하는것인데요..사실 이것은
경기변동에 크게 민감하지 않죠 그 이유는 한계소비비용등 다양한 설명이 필요한데 넘어가도
되구여..

 

네번째 PPI(Producer Price Index)생산자 물가지수는 제품과 서비스 두가지 품목을 조사한는데요
제품의 경우 공장도가격(부가가치세 합산이전금액) 품목은 공장도가격총합의 1/10000 비중을
차지하는 품목 900여개를 조사하지요. 서비스의 경우 전체거래액의 1/2000 비중을 차지하는
품목 90여개를 조사하지요.

다섯번째 GDP디플레이터 약어로 GDPd라고 합시다.쓰기 힘들어. 앞에서 언급했듯이 물가상승압력정도로 해석하는데요. 요거이 식은 명목GDP/실질GDP * 100이지요. 예를 들자면 명목GDP가 120조실질GDP가 100조라면 GDPd는 120이지요 기본값이 100을 기준으로 20% 물가가 상승했다는 뜻입니다.GDP디플레이터는 통화증가량 목표치를 산출할때 아주 중요한 요소이기도 하구여

 

여섯번째 통화량 통화량은 다음과 같은 경로로 움직이지요..통화량을 증가시키면 다음과 같죠
a.통화량증가=>유동성상승=>금리인하=>소비증가.투자증가=>b.경기.소득증가=>통화수요증가=>금리단기상승=>C.기대인플레발생=>금리추가상승


경제용어로 a구간을 유동성효과, b구간을 소득효과, c구간을 피셔효과라고 합니다.

즉 경기침체기에 통화량을 증가시켜 금리를 인하시키면 단기적으로 경기부양효과를 보지만 장기적으론물가상승압력을 받게되지요..사실 우리나라같은 개도국의 경우 꾸준한 성장을 전제로 불황이 없다면 통화정책을 통해 물가상승압력은 거의 없다고 보는게 경제이론이지만 맞지 않죠..지금 우린 스태그 플레이션 여러분 스태그 플레이션이 뭔지 알죠 경기침체+물가상승 그야말로 지랄이지요..참고로 그럼 인플레이션은 경기호황+물가상승 디플레이션은 경기침체+물가하락 이렇지요.스테그 플레이션의 정도에 따라 스테그플레이션,마일드스테그플레이션, Severe 스태그플레이션 정도로 구분하는데 내년엔 가장 심각한 Severe 스테그 플레이션을 거치고 아마도 디플레이션으로 빠질 확률이 높지요.나중에 스태그에 관련해서 자세히 다룰 예정이에용.

 

통화량을 보는 통화지표 이건 M1,M2,M3가 있지요. 예전 IMF시절 이전에는 우린 기관중심에서 IMF시끼들이상품중심으로 바꾸라고 해서 바꾸었답니다 2002년도에.어떻게 요렇게
M1=현금통화 + 요구불예금+수시입출식 저축예금(은행의 MMDA, 투신사의 MMF포함)
M2=M1+정기예금+CD,RP,CMA,표시어음등 (2년이상정기예금은 모두 M3임.)

일곱번째 통화유통속도는 쉽게 말해서 만약 한국은행이 10조를 풀었는데 몇번이나 회전했는가 알아보는것임.
많은게 좋다고 할수도 없고 적다고 좋다고 할수 없음 아니 알수없음 몰라 알수가 없어 ㅋㅋㅋㅋ
식은 통화유통속도(V)=명목GDP/통화량 요렇게 구하지요. 헌데 여기서 위에 GDPd를 설명했는데요.
가령 요렇게 바뀌지요 V*통화량=GDPd*실질GDP 자 여기서 식을 쉽게 정리하지요 어떻게 요렇게
통화량 =M, GDPd=P, 실질GDP=Y 그럼 위식을 정리하면 V*M=P*Y이지요 고등해법수학에서 요런식에서로그한 후 미분하면 곱하기가 더하기 된다면서요..그럼 증가율 G를 상수로 놓고 계산식을 다시쓰면VG+MG=PG+YG 요렇게 변하지요.즉 MG=PG+YG-VG로 정리되지요. 그럼 이식을 어디에 적용해서 쓰는가하면 예를들어 우리나라 내년도 물가상승률이 5&, 경제성장률이 4%, 통화유통속도 3% 일때 통화량증가율은?? 다 더하면 12% 즉 내년엔 통화를 12%증가해야 겠구나 인데요..요거이 사후적으로 추세를 알수 있는거라
경기예측수단으로는 유용성이 없다고 합니다.괜히 공부했지요..ㅋㅋㅋㅋㅋ

드뎌 마지막 금리 이네요..금리는 다 알죠 쉽게 말해 던 빌려주면 그에 따른 꼬물을 얻어 먹는거지요..우리나라는 공정할인율(Bank rate), 은행대출및 예금금리, 회사채수익율, 콜금리,사채금리 등등인데요 우라나라는 콜시장의 콜금리가 중요하지요..콜시장은 금융사끼리 돈을 주고받는 시장이구요.

공정할인율이란 한국은행이 일반은행에 대출해줄때 금리구요. 회사채수익율의 경우 정부에서 채권발행을 재한하기때문에 정확한 수급조절량을 알기 어렵다고 하네요..그래서 콜시장의 콜금리가 잴루 중요하지요.
금리가 올라가면 반대로 채권,주식,부동산,환율 등은 내려간다고 하는게 기본이론이죠.

.

이글을 다 읽으신 분은 참 대단하신분 나도 오늘 괜히 어제 약속을 해서 약속지킬라고 열라 열심히 썻는데쓰면서 내가 왜 그랬을까 하면서 후회했음 그러나 조회수 1을 기록하는 순간이라도 그분을 위해서 열심히 열심히 써볼랍니다. 이상요.

Posted by kevino
,
개인적으로 발표할 기회가 있어서 만들어 놓은 프리젠테이션 장표입니다.

Posted by kevino
,

미네르바 글 모음

경제 2008. 12. 4. 14:08
지금까지의 다음 아고라의 미네르바글을 정리한 문서 파일


Posted by kevino
,
  • 경제토론 내가 요즘 사장들에게 하는 컨설팅(2)... [0]
  • 소나티네 소나티네님프로필이미지
  • 번호 427611 | 2008.12.03 IP 211.180.***.165
  • 조회 44 주소복사

안녕하십니까?

 

여러분과 약속한데로 추천수 200이 넘어서 다시 글을 올립니다.

 

아무튼 지난번 글 많이 읽어주셔서 감사드리구요..

 

오늘은 안전자산인 채권과 투자시 가져야 할 심리에 대해서 간략하게 말씀드리고자 합니다.

 

 

- 채권 (안전자산이자 투자자산의 한 종류) -

 

일반인들에게 채권은 친숙하면서도 또한 낯선 이름이기도 합니다.

 

우리가 이용하는 금융상품의 대부분이 채권으로 운용이 되는데 채권의 가치 , 활용에 대해서는

 

많이 모르는 경우가 대부분인듯 합니다.

 

하지만 채권은 그 시기와 적절한 활용을 통해서 안전하면서도 수익 또한 가져갈수 있는 구조이므로

 

간략하게나마 꼭 아셔야 할부분만 쉽게 언급하도록 하겠습니다.

 

우선 채권은 국채,지방채,특수채,통안채,금융 1,2채, 회사채 1,2 정도로 구분할수 있습니다.

 

1. 국채,지방채,특수채,통안채(국가가 발행)

2. 금융1채(은행이 주로 발행)

3. 금융2채(카드,캐피탈,종금사가 주로 발행)

4. 회사채1,2(일반 회사가 발행)

 

예를 하나 들겠습니다.

 

제가 OO화학 입니다.

 

우리회사가 사업확장을 위해 자금이 필요합니다.

 

3000억이라는 자금이 5년정도 필요하므로 5년짜리 3000억 채권을 발행하려 합니다.

 

본드웹  <----  이 싸이트 가셔서 금리라는 부분을 클릭하시면 시가평가표라는 것이 나옵니다.

 

회사가 채권을 발행하기 위해서는 우리가 알고 있는 한신평,한기평,한신정 3개기관 중 2개 이상의

 

평가기관에 의뢰해 회사 평가를 받아야 합니다.

 

oooo평가라는 회사들이 위에 언급한 3개 회사라고 보시면 되고 증권업협회에서도 등급을 매길수도 있다고 합니다.

 

결론은  OO화학이 두개 평가기관에서 BBB-(트리플 비 마이너스)를 받았다고 가정한다면

 

아까 언급한 시가평가표에서 회사채 1(무보증채 = 회사 담보없는 신용채) 3년짜리가 이 회사

 

채권의 기준 금리가 됩니다.

 

물론 그 금리가 기준점이지 그 금리조건으로 발행되는것은 아닙니다.

 

회사 사정이 시장에서 현재 좋은 평가를 받는 다면 금리가 더 낮게 발행될것이고 만약 좋지 않다면

 

가산금리를 얹어서 발행되게 됩니다.

 

몇달전 우리나라가 외평채(외국평형환기금채권) 10억 달러를 발행하기 위해 가산금리를 200bp

 

를 더했음에도 불발된적이 있었습니다.

 

한국이라는 나라도 외국 평가기관에서 평가를 하고 그 등급과 등급에 맞는 채권 발행 금리가 있습니다.

 

200bp를 가산했다면 연이율 7%발행금리가 기준인데 7% + 2% = 9% 로 제시했다고 보면 쉽게 이해하실듯합니다      (1% = 100bp)

 

우리가 주로 이용하는 금융상품의 구조는 다음과 같습니다.

 

1.은행예금(대부분 국채 + CD + 콜)

2.MMF(국채 40% + 회사채 BBB- 이상 30% + CD + 콜)

 

CD는 여러분이 대부분 아시리라 믿고 90일짜리가 주로 유통되고, 콜이란 금융기관끼리 어떤날은 100억이 모자라고 어떤날은 100억이 남는다면 모자랄때 마다 CP(기업성어음,1년미만 채권이라 보시면 될듯)를 발행하고 남을때마다 예금하는 구조가 번거롭기 때문에 1~3일 정도 금융기관끼리 이런 모자라고 남는 자금을 서로 빌리고 빌려주는 초단기 자금이라 보시면 되고 콜은 여러분들의 예금부분 중  입출금 되는 부분에 대한 유동성을 확보해줍니다.

 

참고로 시가평가표 맨 윗단의 국고채 3년물 금리가 우리나라 은행의 1년만기 예금의 기준금리란 사실은 다 아시겠지만 한번 노파심으로 언급드립니다.  ^^

 

지금부터 본론입니다.

 

채권은 금리 변동에 따라서 채권 가격자체 바뀝니다.

 

물론 채권 인수 쪽에서 만기까지 갖고 갈수 있지만 대부분의 채권은 발행후 유통시장에서 활발하게 거래됩니다.

 

채권금리 상승 ---> 채권가격 하락

채권금리 하락 ---> 채권가격 상승

 

제가 그림 삽입할줄 몰라서 말로 그래프를 설명드릴테니 양해해주십시요.

 

가로축은 금리 세로축은 채권 가격입니다.

 

여러분이 동그란 원을 상상해보십시요

 

그 원을 우리가 보는 시계라고 할때 6시부터 9시 까지의 곡선을 넣으면 바로 그 그래프가 형성됩니다.

 

우리가 과거 IMF시절 국채 금리가 20%까지 오른적이 있습니다.

 

어떤 사람 A가 국채 20% 3년만기 채권 1억을 증권사에서 구매하였습니다.

 

어떤사람 B는 동일 시기에 MMF 1억을 취득하였습니다.

 

금리가 3개월뒤 다시 5% 금리가 되었습니다.

 

B라는 사람은 MMF가 가입시에는 높은 금리였다가 지금은 5%금리로 변했습니다.

 

A라는 사람은 20% ---> 5% 로 동일하게 바뀌었지만 대신에 채권가격이 1억에서 어마어마하게

 

채권가격이 올랐습니다. 제가 아까 말씀드린 그래프 그려보시면 바로 아시리라 생각되구요

 

A라는 사람은 그동안 3개월동안의 이자수익과 더불어 채권을 유통시장에 다시 환매하여 1억 +

채권가격 상승분의 이익을 취했습니다.

 

똑같은 안전자산이라고 한다면 어떤것을 보유하는것이 유리할까요??

 

금리 20%가 내리지 않고 쭈욱~~ 그대로 간다면 어떻하나구요?

 

만기까지 보유하면서 고금리 받으시면 됩니다.

 

MMF도 마찬가지 아니냐구요??

 

MMF = CMA = MMDA 는 비슷한 구조인데 회사채가 편입되어 있습니다.

 

IMF시절 MMF 에 유입된 대우 관련 채권이 백지가 되어버리면서 MMF 자체에 엄청난 손실이 났습니다.

 

일반적으로 MMF는 장부가평가로 금리가 기재됩니다.

 

금리의 매일변동에 의한것을 가격에 편입하지 않는다는 말입니다.

 

하지만 장부가와 시가(실제가격)와의 괴리가 0.5 이상 벌어지면 시가평가로 전환되어 그 손실을 가입고객에 전가시킵니다.

 

채권 금리 상승으로 가격이 떨어지면 고객에게 그 손실을 전가시키는 MMF, 금리 하락으로 인한 가격 상승분은 은행이 먹어버리는 은행예금에 대해서 안전자산이라는 이유만으로 많은 분들이 경기가 불황일수록 많이 소유하시는데 개인이든 기업이든 포트폴리오 맞는 적절한 %만 소유하시길 바라며 은행예금보다 오히려 안전하며 부가 수익 또한 노릴수 있는 국가채권(회사채는 아닙니다 )을

집적 매입함으로 하나의 재테크 수단으로 활요해보시는것도 괜찮다고 생각합니다.

 

정리하자면 금리 상승시에 혹시 채권을 매입했다면 채권가격이 하락하므로 채권 보유하고 고금리를 취하시면 되고, 금리 하락기에는 금리 + 채권가격 인상분을 취하시면 될듯합니다.

 

참고로 금리하락폭이 클수록 , 하락폭이 같지만 만기가 길수록 채권 가격 상승이 더 이뤄진다고 보시면 되겠습니다.

 

제가 만난 사장님들은 IMF 를 겪으신후 IMF학습효과에 대해서 많이 언급들을 하십니다.

 

예전 IMF때 부동산은 이랬고, 주식은 이랬고 , 채권금리는 이랬으니깐 이렇게 하면 되겠다라고

많이들 은행 예금이나 MMF,CMA로 현금 보유를 하고 계십니다.

 

하지만 시장은 일반인들이 예상한대로 수익을 가져다 줄만큼 호락호락하지 않습니다.

 

과거와는 다른 형태의 현금 보유를 하셔야 한다고 생각됩니다.

 

혹시나 오해하실것 같아 빨간글씨로 만들겠습니다. 채권 또한 지금은 보유하셔서는 유리할것이 없다고 봅니다만 멀지 않아 훌륭한 자산 투자의 한 방법이 될것이라 생각되어 언급드리는 것입니다

 

매월 현금의 유동성이 심한 회사인 경우 MMF 보다는 CMA(우리가 접하는 CMA의 90%는 원금보전이 되지 않습니다.원금보전형 CMA를 가입하시길 바라며 원금보전 CMA는 그렇지 않은 CMA보다 금리가 조금 낮습니다.  원금보전을 위한 헤지비용이라 생각하시길 당부드립니다) 상품을 권해드리며 이 또한 금융기관을 분산하시길 권해드립니다.

 

 

 

-투자시 가져야 할 심리

 

모든 거래는 사람과 사람간에 이루어집니다.

 

모든 투자시 100% 이길수는 없다고 하더라도 이기는 확률이 높은 심리상태인분과 정반대 인분들을

 

직업상 많이 만나게 됩니다.

 

채권에 대해 너무 길게 쓴것 같아서 이 주제에 대해서는 다음에 다룰까 합니다.

 

컨설팅을 하는 사람으로서 모든 것들을 쉽게 설명해야하는 숙명을 지닌 저로서는 몸살감기가 4일째라서 (변명입니다만 ㅜ.ㅜ)  채권 부분에 대해서 좀 횡설수설 복잡하게 쓴것 같아서 마음이 심히 편치가 않습니다.

 

너그러이 보아 주시고 혹시 이해가 어렵다는 댓글이 5개 이상 올라오면 추후에 다시 한번 정리해서 글을 올릴까 합니다.

 

여러분들도 감기 조심하십시요. 1분에 한번씩 터지는 마른기침때문에 잠을 통 잘수가 없네요

 

지금까지 졸렬한 제 글을 읽어 주셔서 감사드립니다. 꾸벅 (__)

 

 

 

 

 

 

 

 

 

 

 

 

Posted by kevino
,

DCT(이산코사인변환) - jpeg내용 포함.

지식/이미지 프로세싱 2007/09/19 15:33

JPEG

JPEG(보통 ‘제이펙’이라고 읽는다.)은 높은 압축 효율 때문에 GIF와 함께 인터넷에서 가장 널리 쓰이는 그래픽 파일 포맷이다. JPEG은 Joint Photographic Experts Group이라는 위원회에서 정한 그래픽 이미지 압축에 관한 표준을 의미한다. JPEG이라는 이름도 이 위원회의 이름에서 유래한 것이다. (이와 비슷하게 동화상 압축에 관한 표준이 만들어졌는데 그것이 바로 MPEG이다. MPEG은 Motion Picture Experts Group에서 만든 표준이다.) JPEG 표준은 ISO(국제표준화기구) 10918-1에 정의되어 있다. JPEG 표준은 그래픽 이미지 압축에 대한 표준만 정해놓았을 뿐 구체적인 구현 방법은 정의하고 있지 않다. 우리가 지금까지 살펴본 BMP, PCX, GIF 그래픽 파일들은 어떤 헤더 구조를 가지고 있으며 그래픽 정보를 어떻게 저장하는지 각 그래픽 파일 규격에 구체적으로 정의되어 있다. 하지만 JPEG 표준은 그래픽 파일 포맷에 대한 규격은 전혀 언급하고 있지 않다. 심지어 어떤 방식의 색상 체계를 쓰는지도 정의되어 있지 않다. 구체적으로 어떤 색상 체계를 사용하며 어떤 파일 포맷으로 그래픽 이미지를 저장하는지에 대한 규격은 JFIF(JPEG File Interchange Format)에 정의되어 있다. JFIF는 C-Cube Microsystems의 Eric Hamilton에 의해 만들어졌으며 누구나 사용할 수 있도록 public domain에 공개되어 있다. 우리가 흔히 접하는 확장자가 JPG인 JPEG 그래픽 파일은 대부분 JFIF로 되어있다. 사실 JFIF는 JPEG 위원회나 어떤 기구에 의해 표준으로 정해진 포맷은 아니다. 하지만 시간이 가면서 널리 쓰이다 보니 표준 아닌 표준이 되어 버렸다. JPEG 위원회에서 뒤늦게 SPIFF(Still Picture Interchange File Format)라는 파일 포맷 표준을 내놓았지만 이미 수 많은 JPEG 이미지 파일들이 JFIF로 되어 있기 때문에 그렇게 각광을 받지는 못하고 있다. 여전히 수 많은 그래픽 소프트웨어들이 JPEG 이미지 파일로 JFIF를 사용하고 있다. 우리가 살펴볼 JPEG 이미지 파일도 JFIF이다.

JPEG의 종류 :

ISO10918-1 표준은 그림 1과 같이 압축 방식, 코딩 방식, 샘플링 크기 등에 따라 JPEG 모드를 여러 개로 나누어 놓았다.

JPEG

Sequential

Progressive

Lossless

Hierarchical

Huffman

Arithmetic

Huffman

Arithmetic

Original

Lossless

JPEG-LS

8 bit

12bit

8 bit

12bit

8 bit

12bit

8 bit

12bit

그림 1 여러 가지 JPEG 모드

Sequential 방식은 그래픽 이미지 맨 위부터 아래로 순차적으로 데이터를 저장하는 방식이고 Progressive 방식은 GIF의 Interlaced 모드와 비슷하게 그래픽 이미지를 여러 번 스캔하여 점진적으로 이미지가 뚜렷하게 보이도록 하는 방식이다. GIF의 Interfaced 모드는 몇 줄씩 건너뛰면서 여러 번에 걸쳐 그래픽 이미지를 출력한다. 매번 출력 때마다 그 전에 비어있던 줄을 채워 넣어 그래픽 이미지를 완성한다. JPEG progressive 방식도 여러 번에 걸쳐 그래픽 이미지를 출력하지만 GIF처럼 그림의 일부만 출력하는 것이 아니라 일단 전체 이미지를 모두 출력한다. 단, 마치 포커스가 제대로 맞지 않은 사진처럼 흐릿한 이미지만 출력한다. 그 다음 출력 때 점점 포커스가 맞추어지는 것처럼 보다 더 명확한 이미지를 출력한다. GIF의 경우와 마찬가지로 전체 데이터를 다 전송하지 않고도 어떤 이미지인지 알 수 있게 하기 위해 이런 방식을 사용한다. Hierarchical 방식은 Progressive 방식의 보다 더 진보된 형태이다. 같은 그래픽 이미지를 표현하고 있지만 화질이 서로 다른 이미지를 frame 단위로 여러 개 저장하는 방식이다. 전송 속도가 느린 경우 원하는 화질의 이미지 frame만 전송할 수 있다.

Lossless 방식은 말 그대로 화질 저하가 없는 방식이다. 뒤에 설명하겠지만 JPEG은 높은 압축률을 구현하기 위해 사람 눈이 구분하지 못할 정도로 미세하게 데이터를 생략하는 방식을 사용한다. 그래서 BMP 또는 GIF 그래픽 이미지에서 JPEG 이미지로 변환을 하면 약간의 화질 저하가 있다. BMP --> PCX --> BMP 변환을 아무리 여러 번 수행해도 화질의 변화가 없지만 BMP --> JPEG --> BMP 변환을 수행하면 할수록 점점 화질 저하가 누적된다. Lossless 방식은 전혀 압축을 하지 않는 대신 화질의 변화를 주지 않는 방식이다. JPEG-LS 역시 화질의 변화 없이 저장하는 방식인데 원래 Lossless 방식과는 구현 방법이 다르다.

GIF 그래픽 파일에서 LZW 코딩 방식으로 데이터를 압축 저장하듯이 JPEG도 그래픽 데이터를 압축해서 저장하기 위해 Huffman 코딩이라는 압축 방식을 사용한다. Arithmetic 방식은 구현 방법만 다를 뿐 Huffman 코딩 방식과 똑같은 코딩 방식이다. Arithmetic 방식은 특허로 보호 받기 때문에 함부로 사용할 수 없다.

또한 JPEG 그래픽 이미지는 각 픽셀의 색상을 8비트 또는 12비트로 표현할 수 있다. 우리가 흔히 접하는 JPG 파일은 8비트로 색상을 표현한다.

이렇게 많은 종류의 JPEG 모드 가운데 가장 널리 사용되는 방식은 Sequential – Huffman – 8비트 방식이며 Progressive - Huffman - 8비트 방식의 JPEG 파일도 많이 쓰인다.

JPEG 파일의 원리 :

JPEG 파일, 엄밀하게는 JFIF 포맷의 원리와 구조에 대해 간단하게 알아보자. JPEG 파일은 그림 2와 같은 과정을 거쳐 압축이 된다.

그림 2 JPEG 압축 과정

Sampling은 RGB 색상 체계를 Y-Cb-Cr 색상 체계로 변환하는 과정이다. 이때 Cb, Cr 성분을 구할 때 일부 성분들은 생략되므로 압축의 효과를 가져온다. DCT는 샘플링된 데이터를 코사인 함수의 합으로 변환하는 과정이다. 이렇게 변환된 데이터에서 원래 데이터를 크게 변화시키지 않을 만큼 불필요한 성분들을 제거한다. 이 과정을 양자화(quantization)이라고 한다. 양자화를 거처 압축된 데이터는 Huffman 코딩이라는 압축 알고리즘을 통해 압축이 된다. 양자화 과정에서 한번 압축이 일어나고 Huffman 코딩에서 또 한번 더 압축이 일어나 압축 효율이 극대화되는 것이다. 양자화에 의한 압축은 원래 데이터를 일부 제거하기 때문에 JPEG 이미지의 화질 저하의 원인이 된다. Huffman 코딩은 Lossless 압축 방식이므로 JPEG 이미지 화질 저하와는 관련이 없다.

이렇게 압축된 JPEG 이미지를 복원하려면 위의 과정을 역순으로 행하면 된다. 먼저 Huffman 디코딩을 통해 압축을 풀어 양자화된 데이터를 얻어낸다. 양자화된 데이터는 역 양자화(de-quantization)을 통해 원래 DCT 성분으로 복원된다. 물론 양자화 때문에 완벽하게 100% 원래 성분들을 모두 복원할 수는 없으나 사람의 눈에는 거의 뜨이지 않을 정도로 복원이 가능하다. 복원된 DCT 성분들은 IDCT 변환을 통해 Y-Cb-Cr 데이터로 변환된다. 이렇게 해서 얻은 Y-Cb-Cr 데이터는 Up-sampling 과정을 통해 다시 R,G,B 색상 체계로 변환되어 원래 모습을 찾게 된다. 물론 100% 똑같은 이미지는 아니지만.

지금까지 설명한 과정들이 아마도 쉽게 들어오지 않을 것이다. 보다 더 자세하게 각 과정들을 설명하도록 하겠다.

색상 체계 : JPEG 파일이 사용하는 색상 체계는 Y-Cb-Cr 색상 체계로 앞에서 살펴본 YIQ 색상 체계와 비슷한 방식이다. Y는 밝기를 나타내고 Cb, Cr이 색상을 나타낸다. 원래 Y는 0에서 1사이, Cb, Cr은 –0.5에서 0.5 사이의 값을 가지지만 JPEG 파일은 Y, Cb, Cr 모두 0에서 255의 범위를 가진다. 다음은 RGB에서 YCbCr, YCbCr에서 RGB로 변환하는 공식이다.

Y = 0.299 R + 0.587 G + 0.114 B
Cb = - 0.1687 R - 0.3313 G + 0.5 B + 128
Cr = 0.5 R - 0.4187 G - 0.0813 B + 128

R = Y + 1.402 (Cr-128)
G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)
B = Y + 1.772 (Cb-128)

JPEG 파일은 YCbCr 세 개의 성분 가운데 어느 한 성분(보통 Y성분)만 저장하거나 세 성분 모두를 저장할 수 있다. Y성분만 저장하는 것은 256 level gray 색상으로 저장하는 것을 의미한다. 실제 JPEG 파일에 Y,Cb,Cr 데이터가 저장될 때는 128씩 뺀 값이 저장된다.

Sampling : 지금까지 살펴본 BMP, PCX, GIF와 같은 그래픽 파일들은 한 픽셀의 색을 나타내기 위해 R, G, B 색상 체계를 사용하였으며 3가지 성분 모두 같은 비율로 저장되었다. 하지만 JPEG 파일에서는 Y, Cb, Cr이 서로 다른 비율로 저장될 수 있다. 예를 들어 매 픽셀의 Y 성분을 모두 저장하는 반면 Cb, Cr은 한 픽셀씩 건너 뛰면서 저장할 수도 있다. 이와 같이 전체 픽셀 가운데 일부 픽셀의 데이터만 선별하여 저장하는 방식을 sampling이라고 한다.

JPEG 파일은 샘플링하는 간격을 샘플링 주기(sampling frequency)로 나타내는데 샘플링 주기는 각 성분의 샘플링 간격의 역수비로 나타낸다. Y 성분은 매 픽셀 마다 샘플링하고 Cb 성분은 두 번째 픽셀마다 샘플링하고 Cr 성분은 네 번째 픽셀마다 샘플링한다면 YCbCr의 샘플링 주기는 4:2:1 이 된다. 사람의 눈은 밝기(Y) 성분에 더 민감하기 때문에 보통 Y 성분의 샘플링 주기가 더 크다. 물론 꼭 Y 성분의 샘플링 주기가 커야 되는 것은 아니다. 필요하다면 Cb, Cr의 샘플링 주기가 더 클 수 있지만 그런 경우는 거의 없다.

또한 가로 방향의 샘플링 주기와 세로 방향의 샘플링 주기가 틀릴 수도 있다. 즉, 가로 방향으로는 모든 픽셀의 데이터를 다 저장하고 세로 방향으로는 한 픽셀 씩 건너 뛰면서 데이터를 저장할 수도 있다. JPEG 파일이 허용하는 최대 샘플링 주기는 4이다.

JPEG 파일에서 주로 쓰이는 샘플링 주기는 2:1:1 또는 1:1:1이다. 이와 같이 각 성분의 샘플링 주기를 다르게 하는 이유는 화질의 크게 떨어뜨리지 않고 데이터의 양을 줄이기 위해서 이다. 가로, 세로 방향의 YCbCr 샘플링 주기를 각각 2:1:1로 하면 1:1:1로 하는 것보다 화질의 저하는 다소 있을 수 있으나 데이터 양을 반으로 줄일 수 있다. 이와 같이 일부 픽셀 데이터만 샘플링하는 것을 Down-sampling이라고 하고 반대로 down sampling된 데이터를 원래 픽셀 개수로 늘이는 것을 Up-sampling이라고 한다. 다운 샘플링하는 방법은 여러 가지가 있을 수 있다. 단순하게 일정 간격마다 건너 뛰면서 픽셀 데이터를 저장할 수도 있고 일정 간격 내의 모든 픽셀 데이터들의 평균을 저장할 수도 있다. 후자가 좀 더 나은 방식인데 어떤 방식으로 샘플링하느냐는 그래픽 소프트웨어와 같은 어플리케이션 프로그램에 의해 결정된다. 그림 3은 샘플링의 예이다. 첫번째 경우는 픽셀 모두를 샘플링하는 경우이고 두 번째는 한 픽셀씩 건너 뛰면서 데이터를 샘플링하는 것이고 세 번째의 경우는 4 픽셀의 평균을 샘플링하는 것이다. 이 세가지 경우 샘플링 주기는 2:1:1이다. 두 번째와 세 번째는 샘플링 주기는 같다. 샘플링 방식만 다를 뿐이다.

그림 3 샘플링의 예

DCT와 양자화 : DCT란 Discrete Cosine Transform(이산 코사인 변환)의 약자로 JPEG 압축 기술의 핵심이라 할 수 있다. DCT는 임의의 데이터 배열을 코사인 함수의 합으로 표현할 수 있다는 성질을 이용한 것이다. 예를 들어 임의의 데이터 배열 f를 코사인 함수의 합으로 표현하면 다음과 같다.

이때 코사인 함수의 진폭 F를 DCT 계수(DCT coefficient)라고 하고 새로운 배열 F를 구하는 것을 DCT라고 한다. DCT 계수는 다음과 같이 구할 수 있다.

DCT 계수를 이용해 원래 데이터 f를 구하는 것을 IDCT(Inverse Discrete Cosine Transform)라고 한다. N개의 데이터 f를 DCT로 변환하면 N개의 DCT 계수 F를 구할 수 있다. 예를 들어 표 1의 f와 같이 8개의 원소로 이루어진 배열이 있다고 해보자. DCT 변환을 하면 8개의 DCT 계수 F를 구할 수 있다. DCT 계수들 중 0차 계수는 다른 계수들과 달리 코사인의 함수가 아니기 때문에 DC 계수라고 하고 다른 계수들은 AC 계수라고 부른다. 보통 DC 계수 값이 AC 계수 값에 비해 크기 때문에 JPEG 파일은 DC 계수와 AC 계수를 서로 다른 방법으로 저장한다. 구체적인 것은 뒤에 다시 설명하겠다.

n

0

1

2

3

4

5

6

7

f(n)

10

9.59

8.07

8.15

11.02

14.04

13.51

9.28

F(n)

29.58

-3.22

0.24

4.40

-2.39

0.35

-0.44

0.08

표 1 DCT 변환의 예

DCT 계수 F를 이용해 IDCT를 수행하면 다시 원래 데이터 f를 구할 수 있다. IDCT를 수행할 때 높은 차수의 DCT 계수(n이 큰 DCT 계수)를 생략할 수도 있는데 이 경우 원래 데이터와 100% 똑같지 않지만 상당히 비슷한 값으로 복원해 낼 수 있다. 그림 4는 DCT 계수를 1개에서부터 8개까지 사용해 IDCT를 수행한 경우 복원된 값을 그래프로 보여주고 있다.

점선이 IDCT로 복원된 값이고 실선이 원래 데이터이다. DCT 계수를 많이 쓸수록 원래 데이터에 근접한 결과를 얻을 수 있음을 알 수 있다. 하지만 N=5, 즉 5차 DCT 계수까지만 사용해 IDCT를 해도 원래 데이터와 상당히 유사한 결과를 얻을 수 있다. 여기에 JPEG 압축의 비밀이 들어 있는 것이다. DCT 계수를 모두 다 저장하지 않고 일부만 저장하여도 나중에 복원할 때 원래 데이터와 상당히 유사한 형태로 복원을 할 수 있는 것이다. 이와 같이 DCT 변환된 데이터 중 일부를 버리는 작업을 양자화(Quantization)라고 한다. JPEG 이미지로 변환할 때 약간의 화질 저하가 생기는 이유도 바로 양자화 때문이다.

그림 4 IDT로 복원할 때 사용한 계수의 개수에 따라 복원 정도가 달라진다.

그러나 양자화가 만능은 아니다. 그림 5는 서로 다른 유형의 데이터를 DCT하고 N=5로 양자화한 것을 다시 IDCT로 복원한 것이다. 왼쪽 그림의 경우 거의 완벽하게 복원이 되었으나 오른쪽 그림의 경우는 제대로 복원이 되지 않았다.

그림 5 양자화가 적합한 경우와 그렇지 않은 경우.

양자화가 힘을 발휘하려면 데이터들의 변화가 되도록이면 적어야 한다. 그래서 색의 변화가 극단적으로 일어나는 도형 이미지를 JPEG 이미지로 만들면 자연스럽지 못한 것도 양자화 때문이다. 그림 6을 보자. 왼쪽 그림은 원래 이미지이고 오른쪽 그림은 JPEG으로 저장한 이미지이다. 도형의 모양과 색이 왜곡된 것을 볼 수 있다.

그림 6 JPEG 이미지로 저장할 때 데이터 손실이 생긴다.

그러나 사진의 경우 색의 변화가 심한 부분이 적기 때문에 양자화를 해도 화질의 저하가 그리 크지 않다. 그래서 JPEG은 사진 이미지에 보다 더 적합한 포맷이다.

앞에서 살펴본 DCT, IDCT는 1차원인데 실제 JPEG 이미지에서는 2차원 DCT, IDCT를 사용한다. 샘플링한 픽셀 데이터를 8x8 블록으로 나누어 각 블록마다 2차원 DCT를 수행한 뒤 양자화를 거쳐 데이터 양을 줄인다. 2차원 DCT, IDCT는 다음과 같이 정의된다.

위의 식을 간단하게 행렬로 표시하면 다음과 같다.

JPEG에서는 N은 항상 8이며 f, F는 8x8 행렬이다. 변환 행렬 M은 다음과 같이 정의된다.

MT 는 행렬 M의 Transpose 행렬로 행렬 의 행과 열을 서로 뒤 바꾼 것이다. 즉, MT (i,j)=M(j,i)이다.

JPEG 파일 안에는 8x8 크기의 Quantization table이라는 것이 보관되어 있는데 이 테이블을 이용해 8x8 DCT 계수를 양자화한다. DCT 계수를 1대1로 대응되는 quantization table 값으로 나눈 뒤 반올림 해주면 양자화된 DCT 행렬을 얻을 수 있다. 이렇게 양자화된 DCT 행렬은 대부분의 값이 0이 된다. 양자화된 DCT 행렬을 다시 원래 상태로 돌리려면 단순히 quantization table 값을 곱해주면 된다.

Interleave와 non-interleave 방식 : JPEG 파일은 DCT를 수행하기 위해 샘플링 데이터들을 8x8 크기의 블록으로 나누어야 한다. 이렇게 나뉘어진 8x8 크기의 데이터 블록을 Data Unit이라고 부른다. 가로 세로 샘플링 간격이 1 x 1 픽셀이라면 8 x 8 픽셀 블록이 하나의 데이터 유닛이 되고 가로 세로 샘플링 간격이 2 x 2 픽셀이라면 16 x 16 픽셀 블록이 하나의 데이터 유닛이 된다. 한 데이터 유닛의 픽셀 데이터를 샘플링하여 DCT 계수를 구하고 양자화를 한 뒤 저장을 한다. 그림 이미지의 위에서부터 아래로, 왼쪽부터 오른쪽으로 가면서 샘플링-DCT-양자화를 반복한다.

Y,Cb,Cr 중 한 가지 성분만 저장할 때는 단순하게 (8 * 가로 샘플링 간격) x (8 * 세로 샘플링 간격) 픽셀 씩 나누어 DCT를 수행해 맨 오른쪽 윗부분부터 순차적으로 저장하면 된다. 하나 이상의 성분을 저장할 때는 조금 복잡해 진다. Y, Cb, Cr 각 성분의 샘플링 주기가 모두 같을 때는 하나의 8 x 8 블록 내에 있는 Y, Cb, Cr 데이터를 순차적으로 저장하고 그 다음 8 x 8 블록의 Y, Cb, Cr 데이터를 순차적으로 저장한다. 샘플링 주기가 다를 때는 샘플링 주기가 가장 작은 성분을 기준 블록으로 삼고 이 블록 안의 Y, Cb, Cr 데이터를 순차적으로 모두 저장한 뒤 그 다음 기준 블록의 Y, Cb, Cr 데이터를 저장한다. 이 기준 블록을 MCU(Minimum Coded Unit)이라고 한다. 이와 같이 여러 개의 성분을 번갈아 가면서 저장하기 때문에 하나 이상의 성분을 저장할 때를 Interleaved 방식이라고 한다. 반면에 하나의 성분만 저장할 때는 Non-interleaved 방식이라고 한다. 그림 7은 Non-interleaved 방식으로 저장하는 예이다.

그림 7 Non-interleave 방식

그림 8은 Y, Cb, Cr의 샘플링 주기가 2:1:1인 경우 interleaved 방식으로 저장하는 예이다. Y성분은 모든 픽셀에서 샘플링하고 Cb, Cr 성분은 한 픽셀씩 건너 뛰면서 샘플링한다. 따라서 Y의 8 x 8 블록은 8 x 8 픽셀로 이루어져 있지만 Cb, Cr의 8 x 8 블록은 16 x 16 픽셀로 이루어져 있다. 즉, MCU는 16 x 16 픽셀로 되어 있으며 각 MCU 별로 Y, Cb, Cr 성분을 저장하게 된다.

그림 8 Interleave 방식

첫번째 MCU 블록에서 Y1, Y2, Y3, Y4 블록의 순으로 Y 데이터를 저장하는데 각 데이터 유닛의 크기는 8 x 8 픽셀이다. 다음 16 x 16 픽셀의 Cb, Cr 데이터(Cb1, Cr1)를 순차적으로 저장하면 첫번째 MUC 블록의 저장이 끝이 난다. 그 다음 두 번째 MCU 블록에서 Y5, Y6, Y7, Y8 블록 순으로 Y 데이터를 저장하고 Cb2, Cr2 데이터를 저장한다. 이런 방식으로 맨 마지막 8번째 MCU 블록까지 저장한다.

Interleaved 방식이던 Non-interleaved 방식이던 항상 MCU 의 배수 크기로 저장을 해야 한다. 따라서 그림 이미지 크기가 정확하게 MCU의 배수 크기가 아니면 실제 크기보다 더 크게 저장이 된다. 물론 복원할 때 원래 그림 이미지 크기에 맞게 불필요한 부분을 잘라낸다. MCU 크기에 맞지 않는 블록에서는 비어있는 부분은 보통 마지막 픽셀을 중복해서 채워넣는다.

JPEG 파일에는 각 성분의 샘플링 주기에 대한 정보와 그림 이미지의 크기에 대한 정보만 있을 뿐 MCU의 크기, 개수에 대한 정보는 저장되어 있지 않다. 따라서 다음과 같은 공식으로 MCU의 크기와 개수를 계산해 낼 수 있다.

MCU 폭 = 최대 샘플링 주기 * 데이터 유닛 폭(항상 8)
MCU 높이 = 최대 샘플링 주기 * 데이터 유닛 높이(항상 8)
가로 방향 MCU 개수 = (이미지 폭 + MCU폭 – 1) / MCU 폭
세로 방향 MCU 개수 = (이미지 높이 + MCU높이 – 1) / MCU 높이

Huffman Coding : 샘플링-DCT-양자화를 거친 데이터를 바로 그냥 저장하는 것이 아니고 한번 더 압축을 해서 저장을 한다. GIF 파일에서 LZW 코딩을 했듯이 JPEG 파일에서는 Huffman 코딩이라는 방법을 써서 압축을 한다. Huffman 코딩의 원리는 간단하다. 보통 한 픽셀 데이터의 길이는 8비트로 고정이 되어 있는데 Huffman 코드는 데이터의 빈도수에 따라 그 길이가 다르다. 빈도수가 많은 코드일수록 길이가 짧기 때문에 길이가 고정된 경우보다 전체 데이터의 크기가 작은 것이다.

Huffman 코드를 만드는 방법은 여러 가지가 있는데 JPEG 파일은 코드 길이(Code length)를 이용한 방법을 쓰고 있다. 알고리즘은 다음과 같다.

1. 데이터 배열에서 각 데이터들의 빈도수를 구한다.
2. 데이터들의 빈도수를 이용해 코드의 길이를 구한다.
3. 코드 길이를 이용해 Huffman 코드를 구한다.

예를 들어 다음과 같은 데이터 배열의 Huffman 코드를 구해보자.

BABDAGBFBDBDBABGGBCDBGBDBGBEFGFFGBFG

데이터의 종류는 A에서 G까지 7가지 이고 각 데이터들의 빈도수는 다음과 같다.

데이터

빈도수

데이터

빈도수

A

3

B

13

C

1

D

5

E

1

F

5

G

8

이를 이용해 코드의 길이를 구한다. 먼저 각 데이터들의 코드 길이를 나타내는 변수를 하나씩 할당해주고 모두 0으로 초기화한다. 다음 가장 빈도수가 작은 데이터 두 개를 골라 합친다. 그리고 각 데이터의 빈도수의 합을 새로운 빈도수로 넣어주고 코드 길이를 1씩 증가시킨다. 아래의 예에서는 빈도수가 1인 C와 E를 합쳐주고 코드 길이를 1씩 더했다. 새로운 테이블에서 다시 가장 빈도수가 작은 데이터 두 개를 골라 합치고 코드 길이를 1씩 증가시킨다.

이 작업을 모든 데이터가 다 합쳐질 때까지 반복한다.

이제 최종적으로 남은 코드 길이가 Huffman 코드의 길이가 된다. 빈도수가 높은 데이터일수록 코드 길이는 작다는 것을 알 수 있다. 다음 알고리즘을 이용해 Huffman 코드를 구할 수 있다.

HuffCodeCount = 0
CurrCodeLength = CodeLength(0)
i = 0
Do While i < NoOfCodes
  Do While CodeLength(i) = CurrCodeLength
   Code(i) = HuffCodeCount
   HuffCodeCount = HuffCodeCount + 1
   i = i + 1
  Loop
  HuffCodeCount = ShiftLeft(HuffCodeCount)
  CurrCodeLength = CurrCodeLength + 1
Loop

이 알고리즘을 한 스텝씩 따라가보면 그림 9와 같은 결과를 얻을 수 있다. 아래 첨자 2는 2진수임을 나타낸다.

그림 9 Huffman code 만들기

마지막 테이블이 최종적으로 구한 Huffman 코드 테이블이다. 이 코드 테이블을 이용해 데이터 배열의 각 데이터들을 Huffman 코드로 바꾸어 주면 압축이 된다. Huffman 코드는 코드마다 길이다 다르기 때문에 한 바이트 안에 여러 개의 코드가 들어갈 수도 있고 두 바이트에 걸쳐 하나의 코드가 들어갈 수도 있다.

얼마나 압축을 할 수 있는지 한번 살펴보자. 원래 데이터들은 A부터 G까지 7가지 이므로 3비트로 표현한다고 해보자. 총 데이터 개수가 36개이므로 전체 데이터 배열의 크기는 3 x 36 = 108 비트이다. 데이터 배열을 Huffman 코드로 표현하면 B는 1비트 코드로 표현할 수 있으며 B의 개수는 13개이므로 13비트가 필요하다. G의 개수는 8개이며 3비트로 표현할 수 있으므로 24비트가 필요하다. 이런 식으로 필요한 모든 비트 수를 계산하면 표 2와 같이 총 89비트가 필요하다. 따라서 압축 효율은 89/108 = 89.8%가 된다.

데이터

코드 길이

개수

필요한 비트

B

1

13

13

D

3

5

15

G

3

8

24

F

3

5

15

A

4

3

12

C

5

1

5

E

5

1

5

36

89

표 2 압축 효율

Huffman 코드로 압축된 데이터를 원래 데이터로 복원하는 것은 더 간단하다. 압축된 파일 안에는 Huffman 코드 테이블을 함께 저장한다. Huffman 코드 테이블을 참조하여 원래 데이터로 바꾸기만 하면 된다. 예를 들어 앞에서 살펴본 데이터 배열의 첫 4개의 데이터를 Huffman 코드로 표현하면 다음과 같다.

BABD ... -->  0112 1002 1002 ...

그런데 Huffman 코드는 길이가 가변이기 때문에 어디에서부터 어디까지가 하나의 코드인지 쉽게 구분이 가지 않는다. 하지만 Huffman 코드를 잘 살펴보면 해답을 찾을 수 있다. 서로 다른 코드는 코드의 맨 앞부분이 서로 중복되지 않는다는 특징을 가지고 있다. 예를 들어 B를 가리키는 코드는 02인데 02로 시작되는 코드는 하나도 없다. 마찬가지로 1002로 시작하는 코드는 D밖에 없다. 따라서 코드 길이 순서대로 코드 테이블을 검색하여 최초로 일치하는 코드가 나오면 그 코드가 바로 찾으려는 코드가 된다. 위의 예에서 첫번째 비트 데이터는 02인데 Huffman 코드 테이블에서 02으로 시작하는 코드는 B 밖에 없으므로 첫번째 비트가 B를 가리키는 Huffman 코드임을 알 수 있다. 그 다음 비트는 12인데 코드 길이가 1인 코드는 02밖에 없으므로 그 다음 비트를 읽어봐야 한다. 그 다음 비트는 12인데 코드 길이가 2인 코드는 없으므로 또 다음 비트를 읽어야 한다. 그 다음 비트까지 읽으면 지금까지 읽은 코드는 1112이 된다. 하지만 Huffman 코드 테이블에는 1112코드는 존재하지 않는다. 따라서 또 다음 비트를 더 읽어와야 한다. 그 다음 비트까지 읽으면 11102이 되는데 11102은 Huffman 코드 테이블에 존재하며 A를 가리킨다. 두 번째 코드를 찾은 것이다. 그 다음 비트는 02인데 02은 B를 가리킨다. 세 번째 코드도 찾았다. 마찬가지로 Huffman 코드 테이블에 존재하는 코드가 나올 때까지 다음 비트들을 읽는다. 그러면 그 다음 코드는 1002가 됨을 알 수 있고 1002는 D를 가리킨다.

JPEG 파일에서 Huffman 코딩 : JPEG 파일에서는 DCT-양자화를 거친 데이터를 Huffman 코딩 방식으로 압축을 한다. Huffman 코드의 최대 길이는 16비트로 제한되어 있다. DCT 계수 가운데 DC 계수와 AC 계수를 따로 분리하여 코딩하고 필요에 따라 YCbCr 성분 별로도 따로 코딩을 한다. Huffman 코딩은 서로 같은 데이터가 많을수록 압축 효율이 좋기 때문에 이렇게 서로 비슷한 성분들끼리 분리하여 코딩을 하는 것이다.

보통 DC 계수의 크기는 AC 계수의 크기보다 크며 양자화된 AC 계수는 대부분이 0이다. AC 계수끼리 묶으면 대부분의 데이터가 0인데 보다 압축 효율을 높이기 위해 0으로 된 데이터들은 PCX 파일에서 사용한 Run-length encoding 방식으로 압축을 한다. 즉, 데이터 자체를 저장하는 것이 아니라 0의 개수를 저장하는 것이다. 0이 아닌 AC 계수와 DC 계수는 Huffman 인코딩을 하는데 값 자체를 인코딩하는 것이 아니고 인접한 값과의 차이를 인코딩한다. 예를 들어 DC 계수 배열이 122, 123, 124, 125, 126 이런 식이라면 실제 값이 아닌 인접한 값과의 차이인 122, 1, 1, 1, 1을 인코딩하는 것이다. 이렇게 하면 서로 똑같은 값들이 많아지기 때문에 값 자체를 인코딩할 때보다 훨씬 더 압축 효율이 높아진다. 이런 이유 때문에 인접한 픽셀들끼리의 변화가 적은 사진 이미지가 도형 이미지보다 압축 효율이 좋다.


이미지 압축 원리
1. BMP (Windows bitmap)
2. PCX
3. GIF (Graphic Interchanging Format)

4. JPEG
5. WMF (Mircosoft Windows Metafile)
6. 부록 - Graphic File Loader 예제 프로그램


JFIF :

지금까지 설명한 원리에 따라 JPEG 이미지가 저장이 되는데 JPEG 파일의 실제 구조는 어떠한지 알아보자. 이미 설명했듯이 JPEG 파일 구조란 JFIF(JPEG File Interchange Format)을 의미한다. JPEG 파일은 그림 1과 같이 여러 개의 블록으로 나뉘어져 있다.

SOI (Start Of Image)
APP0 JFIF Marker
추가 APP Marker (APP0 ~ APP15) 또는 주석 (COM) marker
DQT (Define Quantization Tables)
SOF (Start Of Frame)
DHT (Define Huffman Tables)
SOS (Start Of Scan)
스캔 데이터
EOI (End Of Image)


그림 1 JFIF의 구조

각 블록은 Marker에 의해 구분된다. Marker는 &HFF로 시작되는 두 바이트 데이터로 marker 하나로 끝나는 것도 있고 marker 뒤에 추가 데이터가 더 붙는 것도 있다. 추가 데이터가 더 붙는 경우 marker 뒤에 2바이트의 데이터 길이가 오고 그 다음 추가 데이터가 온다. 데이터 길이는 데이터 길이 필드를 포함한 길이다. 한가지 주의할 것이 지금까지 살펴본 그래픽 파일에서는 상위 바이트와 하위 바이트의 순서가 바뀌어서 저장되어 있는데 JPEG 파일에서는 그 순서가 뒤바뀌어서 저장되지 않는다는 점이다. 예를 들어 &H12 &H3F 순으로 저장되어 있다면 &H3F12가 아니고 &H123F를 가리키는 것이다.

JFIF에서 사용되는 marker는 표 1과 같다.

분류 심볼 설명
추가 데이터 없음 FFD0~FFD7 RST0~RST7 Restart marker
FFD8 SOI Start Of Image
FFD9 EOI End Of Image
추가 데이터 있음 FFC0~FFC2 SOF0~SOF2 Start Of Frame
FFC4 DHT Deine Huffman Tables
FFDA SOS Start Of Scan
FFDB DQT Define Quantization Tables
FFDD DRI Define Restart Interval
FFE0~FFEF APP0~APP15 Application specific data
FFFE COM Commnet

표 1 JFIF에서 사용되는 marker

JPEG 표준에는 이보다 더 많은 marker들이 정의되어 있으나 JFIF에서는 거의 쓰이지 않는다. 각 블록을 더 자세히 살펴보자.

SOI와 APP0 JFIF Marker : 파일의 맨 처음 오는 marker들로 주로 JFIF임을 확인하는 용도로 사용된다. 그 구조는 표 2와 같다.

이름 크기 설명
SOI marker 2 항상 FF D8
APP0 marker 2 항상 FF E0
Data length 2 추가데이터 길이, 바이트 단위, 상위 바이트, 하위 바이트 순으로 저장되며 Data length 필드를 포함한 길이를 나타낸다.
Identifier 5 항상 4A 46 49 46 00. JFIF임을 나타낸다.
Major version ID 1 버전 번호.
Minor version ID 1 버전 번호.
Units 1 그 다음 오는 X, Y 해상도의 단위를 나타냄.

0 - 해상도 사용 안함
1 - 단위 인치 당 픽셀 수
2 - 단위 cm 당 픽셀 수
Xdensity 2 가로 해상도
Ydensity 2 세로 해상도
Xthumbnail 1 미리 보기 이미지의 폭. 미리 보기가 없으면 0.
Ythumbnail 1 미리 보기 이미지의 높이. 미리 보기가 없으면 0.
Thumbnail 가변 미리 보기 이미지. RGB 컬러 순으로 픽셀 데이터가 저장되어 있다.

표 2 SOI와 APP0 JFIF marker의 구조

추가 보조 Marker : APP0 marker 외에 미리 보기 이미지를 추가로 더 넣거나 주석을 달기 위해 몇 가지 marker가 더 올 수 있다. 보통 이들 marker들은 그림 이미지 자체에 전혀 영향을 주지 않으며 어플리케이션 프로그램에서 보조 자료로 쓰일 뿐이다. marker 뒤에 추가 데이터 길이 필드가 오는데 이를 이용해 다음 marker로 건너 뛸 수 있다.

DQT marker : DQT는 양자화 테이블(Quantization table)을 보관하는 블록이다. 표 3과 같은 구조로 되어 있다.

이름 크기 설명
DQT marker 2 항상 FF DB
Data length 2 추가 데이터 길이.
Quantization table   양자화 테이블. 최대 4개의 테이블을 가질 수 있다.

표 3 DQT marker의 구조

JFIF는 최대 4개의 양자화 테이블을 보관할 수 있다. 각각의 양자화 테이블 구조는 표 4와 같다. 테이블 값은 8비트 샘플링의 경우 1바이트, 12비트 샘플링의 경우 2바이트 크기를 가진다.

Table Identifier 1 상위 4비트 : 테이블 값 크기. 0= 1바이트. 1=2바이트.
하위 4비트 : 테이블 ID. 0~3 사이의 값을 가진다.
Table 64 또는 128 양자화 테이블. 8 x 8 테이블이 지그재그 순서로 저장되어 있다. 그림 2참고

표 4 양자화 테이블의 구조


그림 2 양자화 테이블 값이 저장된 순서

SOF marker : SOF는 그림 이미지의 크기 및 샘플링에 관한 정보를 보관하고 있다. 표 5는 SOF 블록의 구조이다.

이름 크기 설명
SOF marker 2 항상 FFC0 ~ FFC2

FFC0 - baseline
FFC1 - extened sequential
FFC2 - progressive
Data length 2 추가 데이터 길이.
Sampling precision 1 샘플링 비트 수 8 또는 12
Image height 2 이미지 높이. 픽셀 단위.
Image width 2 이미니 폭. 픽셀 단위.
No fo components 1 Y, Cb, Cr 성분 수. 1 ~ 3.
Component specific   각 성분에 대한 정보.

표 5 SOF marker 구조

JFIF는 Y, Cb, Cr 세 가지 성분 중 하나 또는 3가지 모두를 저장할 수 있다. 각 성분에 대한 정보는 표 6과 같은 구조로 저장되어 있다.

이름 크기 설명
Component ID 1 각 성분을 구분하기 위한 ID. 0~255 사이의 값을 가질 수 있으나 JFIF에서는 Y는 1, Cb는 2, Cr은 3으로 고정되어 있다.
Sampling Frequency 1 상위 4비트 : 해당 성분의 가로 샘플링 주기 (1~4)
하위 4비트 : 해당 성분의 세로 샘플링 주기 (1~4)
Quantization table ID 1 해당 성분에서 사용할 양자화 테이블의 ID 0 ~ 3의 값을 가진다.

표 6 YCbCr 성분에 대한 정보

SOF는 JPEG 파일 안에 오직 하나만 존재할 수 있다.

DHT marker : DHT는 Huffman 코드 테이블을 보관하고 있는 블록이다. Huffman 코드 테이블은 AC 계수용, DC 계수용이 따로 보관되며 각각 최대 4개의 테이블을 가질 수 있다. 각 테이블의 구조는 표 7과 같다.

이름 크기 설명
DHT marker 2 항상 FF C4
Data length 2 추가 데이터길이.
Huffman table   Huffman table 구조 참고

하나의 Huffman table 구조

이름 크기 설명
Table ID 1 상위 4비트 : Table class. 0은 DC 1은 AC 테이블을 의미.
하위 4비트 : Table ID. 0 ~ 3의 값을 가진다.
Codelength Counter 16 코드 길이가 1 ~16인 코드의 개수를 보관하고 있다.
Symbols 가변 Huffman 코드 순서대로 코드가 가리키는 실제 데이터를 보관하고 있다. 전체 크기는 codelength counter의 총 합.

표 7 DHT marker

SOS marker : SOS는 각 성분들이 어떤 Huffman table을 사용할지 알려주는 블록이다. 그 구조는 표 8과 같다.

이름 크기 설명
SOF marker 2 항상 FF DA
Data length 2 추가 데이터 길이.
Component count 1 성분 개수
Scan description   각 성분이 사용할 Huffman table의 ID
Spectral selection start 1 DCT 를 최적화할 때 사용하는 값.
Spectral selection end 1
Successive approximation 1

표 8 SOS marker

Scan description은 성분의 개수만큼 있는데 각각의 구조는 표 9와 같다.

이름 크기 설명
Component ID 1 각 성분을 구분하는 ID
Huffman table ID 1 상위 4비트 : 해당 성분이 사용할 DC Huffman 테이블의 ID
하위 4비트 : 해당 성분이 사용할 AC Huffman 테이블의 ID

표 9 각 성분의 scan description

SOS가 시작되기 전에 최소한 하나 이상의 DHT, DQT와 하나의 SOF가 있어야 한다.

스캔 데이터 : SOS 바로 다음에 스캔 데이터 블록이 오게 되는데 스캔 데이터는 픽셀들의 색 정보를 샘플링-DCT-양珉?Huffman coding 과정을 거쳐 만들어낸 데이터이다. 이렇게 해서 만들어진 스캔 데이터를 다시 원래 픽셀 정보로 바꾸려면 역으로 Huffman decoding-역양자화(Dequantization)-IDCT-업 샘플링 과정을 거치면 된다.

Restart marker : restart marker (RST)는 유일하게 스캔 데이터 안에 존재하는 marker로 손상된 JPEG을 최대한 복원하기 위해 사용하는 marker이다.

SOS 이전에 DRI(Define Restart Interval) marker로 restart 간격을 정의를 한다. DRI marker의 구조는 표 10과 같다.

이름 크기 설명
DRI marker 2 항상 FF DD
Data length 2 추가 데이터 길이.
Restart interval 2 Restart 간격. 0이면 restart marker(RST)가 쓰이지 않음을 의미.

표 10 Restart marker

DRI에 정의된 restart 간격이 0보다 크면 그 간격만큼의 MCU 마다 RST marker가 놓이게 된다. 예를 들어 restart 간격이 N이라면 그림 3과 같이 N개의 MCU 데이터 마다 RST marker가 놓인다.


그림 3 RST marker

RST marker는 RST0부터 RST7까지 8개가 있는데 순차적으로 나타나며 RST7 다음에는 RST0이 다시 나오게 된다.



출처 : http://php.chol.com/~mrjin 
Posted by kevino
,