맘에 드는 포스트 몇 개 링크…

nmindplus 님처럼 꾸준히 오늘의 링크를 정리하는 건 힘들겠지만, 요 근래 읽었던 포스트들 중에 다른 분들도 읽어보면 좋겠다 싶은 글 몇 개를 추려봤습니다.

꼴찌 서울대생하면 생각나는 후배가 있습니다.
맞지 않는 교수님을 만나 석사과정을 하다 보니 트러블도 있고 성적도 좋지 않았습니다.
(우리 나라 교수님들 아직도 문제 많으십니다. 학생들은 노예가 아닌데 말이죠)
회사 들어와서는 정말 어려운 일들을 척척 해내는, 제가 존경하는 후배 중에 하나가 되었죠.
지금은 실리콘 밸리에서 중추적인 역할을 해내고 있답니다. 늘 자랑스럽습니다.
1등 지방대생하면 생각나는 친구가 있습니다.
자신이 원하는 것이 무엇인지 몰랐기 때문에 시작이 조금 늦었지만
자신이 원하는 것을 찾은 후에는 성실과 열정으로 전진 밖에는 모릅니다.
줄곧 1등을 하고 있으며, 자신의 일을 너무 좋아하는 그런 친구죠.
자신이 원하는 꿈을 향해 오늘도 한발 한발 즐겁게 오르고 있답니다. 늘 자랑스럽습니다.
from: 소프트웨어 이야기: 서울대 꼴지와 지방대 1등

링크만 걸면 안읽어보실 분을 위해 맘에 드는 구절을 인용해봤습니다. 🙂
작은 행복: 세상을 살아가는 방식
http://mbastory.tistory.com/100
서울대 꼴지와 지방대 1등
http://jamestic.egloos.com/1497911
얼마나 멀리 보고 있습니까?
http://jamestic.egloos.com/1522165
무료 음료수의 스낵
http://jamestic.egloos.com/1463659
그 친구들은 안그래도 되는데 말이지
http://jamestic.egloos.com/1382804
폐인 만복래! 소설가 이외수
http://www.dcinside.com/webdc/dcnews/news/etc_list.php?code=succeed&id=7947
기획자가 하는 일, 개발자가 하는 일
http://www.dal.kr/blog/2007/10/20071020_planner.html
혹시나 괜찮은 글들이 많이 올라오는 블로그가 있으면, 추천해주세요~

지름: 무지 푹신 소파

컴퓨터랑 침대 말고 그냥 편하게 묻혀 생각을 정리하기 위한 공간을 만들기 위해 ‘무지 푹신 소파’ 를 질러버렸습니다. 제품 이름이 ‘푹신 소파’ 이고 제조사가 ‘무지’ 인데 붙여써놓으니 뭔가 묘하네요.

Continue reading 지름: 무지 푹신 소파

Math: line fitting

만약 서로 다른 2개의 (x,y) 쌍을 가지고 있다면 아래와 같은 직선의 방정식을 계산해낼 수 있습니다.

이를 아래와 같은 매트릭스 형태로 표현할 수도 있습니다.

그런데 (x,y) 값을 2 쌍보다 더 많이 알고 있다면, 해가 구해낼 수 없게됩니다. 이를 over constraint 라고 하며, over constraint 상태에서 가장 에러가 작은 직선의 방정식을 구해내는 것을 line fitting 이라고 부릅니다.

line fitting 을 하는 방법은 크게 2가지 방법이 있습니다. 첫번째는 에러를 최소화 하는 계수 a, b 를 찾기 위해 편미분을 이용하는 것이고, 두번째로는 pseudo inverse 를 이용하는 방법입니다.

line fitting with differencial equation

편미분을 통해 최적의 직선을 찾아내기 위해 우선 Error 를 아래와 같이 정의해 봅시다.

2차 곡선의 최소값은 기울기가 0이 되는 지점에 있으므로 a, b 각각에 대해 편미분을 한 뒤 기울기가 0 이 되는 지점을 찾습니다.

위 식을 정리하면 아래와 같은 매트릭스로 표현이 가능하며,

역함수를 양 변에 곱해주게 되면 간단히 계수 a, b 를 구할 수 있게 됩니다.

line fitting with pseudo inverse

지금까지 편미분을 이용한 line fitting 을 알아봤는데, 이 경우는 손으로 계산해야하는 것들이 많았지만 pseudo inverse 를 이용하면 계산을 모두 컴퓨터에게 맡길 수 있기 때문에 훨씬 쉽게 직선의 방정식을 구할 수 있습니다.

pseudo inverse 를 이용한 방법을 알아보기 앞서 위 매트릭스를 간단히 아래와 같이 표현하기로 하겠습니다.

X 에 대한 inverse 를 계산할 수 있다면 간단하게 계수 a, b 를 구할 수 있겠지만 불행히도 X 는 inverse 를 가지지 못하기 때문에 X 에 자신의 transpose 를 곱해준 뒤 역행렬을 구하는 방법을 사용하게 되며, 이런 식으로 역행렬을 구해내는 방법을 pseudo inverse 라고 합니다.

식을 정리하고 나니 아래와 같은 간단한(?) 행렬 연산을 통해 계수 a, b 를 계산해낼 수 있겠습니다.

Result

아래 그래프는 (1.1,0.7), (2.1,1.0), (4.3,3.2), (-1.2,-1.1), (-2.4,-2.1), (-3.5,-3.4) 이렇게 6개의 점에 대한 line fitting 결과를 gnuplot 을 이용해서 그래프로 만든 것이며, 6개의 점 사이를 지나는 직선이 구해진 것을 쉽게 확인할 수 있겠습니다.

p.s) 매트릭스 관련된 오퍼레이션들을 다 짜놨더니 이거이거 이런 간단한 것들 돌려보는건 일도 아니네요. 요 근래 뭔가 조급해하고 있었는데, 맘잡고 기초부터 탄탄히 해놓는게 나을 거 같다는 생각이 들어서. 욕심을 줄이고 있습니다. 후훗

코드: https://github.com/Tee0125/linear_regression/blob/master/numpy/numpy_linear_regression.py

CG: 3D Image Rotation

며칠 전 Perspective Projection 을 정리해놓은 김에 3D Image Rotation 도 정리를 해볼까 싶습니다.

Rotation Matrix

3D 이미지 회전은 아래와 같은 행렬을 통해 새로운 좌표를 계산할 수 있습니다. 또한 이 행렬들은 모두 unitary matrix 이기 때문에 Transpose 를 취해줌으로 역행렬을 쉽게 구할 수 있습니다.

z축 기준: (xy 평면에서의 회전)

y축 기준: (zx 평면에서의 회전)

x축 기준: (yz 평면에서의 회전)

Implementation of Image Rotation

처음에는 3차원 공간을 3차원 배열을 사용하여 모델링한 뒤 실제 3차원 좌표를 모두 뒤지며 forward/backward mapping 하는 방법을 통해 3D image rotation 을 구현해보았습니다. 3차원 배열을 이용 512×512 사이즈의 lena image 를 회전시키려면 (512*1.414)^3 만큼의 공간이 필요하게 되고, 저 공간을 모두 뒤지려면 계산 복잡도가 엄청나더군요.

실제 이 방법을 통해 이미지를 회전 시키는 데 ‘분’ 단위 시간이 필요했던 것으로 기억합니다. 게다가 변환을 반복할 수록 이미지의 디그라데이션이 심해졌기 때문에 이건 아니라는 생각이 들더군요. 이런 경우 이미 잘 설계되어 있는 그래픽 라이브러리를 참고하는 것이 좋기 때문에 OpenGL 의 인터페이스를 살펴보며 어떤 식으로 구현하면 좋을 지 생각하기 시작했습니다.

뭐 어짜피 화면이나 이미지로 보여주기 위해선 2D 평면에 projection 하는 것이 필요하므로 매 번 이미지 자체를 돌리기 보다 축을 회전시키고, 마지막에 그 축을 이용해서 원래 이미지를 새로운 좌표 공간으로 매핑시켜주면 되겠다는 결론을 얻었습니다.
우선 x, y, z 좌표를 identity matrix 로 표현한 뒤 R^T * AXIS 를 통해 새로운 축 AXIS’ 를 구할 수 있고, 회전을 시키고 싶은 만큼 위 연산을 반복해준 뒤 forward mapping 을 해주는 것으로 빠르고 훌륭한 품질을 보여주도록 구현하는걸 성공했습니다.

위 이미지는 512×512 사이즈의 lena 이미지를 z축을 기준으로 45도만큼 회전시킨 결과입니다. 왼 쪽은 단순히 forward mapping 을 해준 것이고 오른쪽은 weighted sum 을 이용해서 forward mapping 을 개선해준 것입니다.

결과적으로 Photoshop 등을 이용한 만큼 훌륭한 이미지를 얻어낼 수 있는 것을 확인할 수 있습니다.

Other Results

아래 이미지는 x 축, y축, z축을 기준으로 순서대로 30도씩 회전시킨 이미지입니다. 이런 식으로 계산을 하려면 순서를 뒤집어서 z축, y축, x 축 기준으로 30도씩 회전을 시켜주면 됩니다.

다음은 x축으로 30도, y축으로 60도 만큼 돌린 결과

실제 구현 코드에 관심이 있으신 분들은 아래 링크를 방문하시면 되겠습니다. 이런 걸 하나하나 구현해볼 때마다 느끼는 거지만 openGL 같은 라이브러리를 설계하신 분들은 상상하기 힘들 정도로 똑똑한 것 같아요.

소스:
https://github.com/Tee0125/snippet/tree/master/rotation3d

CG: Perspective Projection

HCI 과제 덕에 심심찮게 프로그래밍을 하게 되네요. 첫 과제 였던 3D rotation 관련을 구현하는 것도 상당히 흥미로웠지만, 두번째 과제인 Perspective Projection 를 구현하는 것은 정말 멋진 경험이었다고 생각합니다.

지난 며칠간 꽤나 재밌게 프로그래밍을 했던 관계로 블로그에도 살짝 정리해보는게 어떨까 하는 생각이 들었는데, 막상 쓸려니 내용이 잘 전해질지 의문이네요.

What is the Perspective Projection?

Perspective Projection 이란 아래의 왼쪽 이미지를 오른쪽 이미지 처럼 변화시키는 것을 얘기합니다. 꼭 저렇게 비뚜러진 이미지를 바로잡는것은 아니고, 이미지가 투영되는 면을 변화시키는 것이라고 생각하시면 됩니다.

이해를 돕기 위해 wikipedia 에서 이미지를 하나 가져왔습니다. 아래 이미지의 연보라색 면이 상이 맺히는 곳이라고 할 때, perspective transform 은 그 보라색 면을 이동시킨 것 같은 효과를 주기 위해 사용합니다.

How to get a projection matrix.

기본 적으로 Perspective Transform 을 위한 식은 다음과 같습니다.

homogenious coordinate 를 사용하고 있으니 x’ 와 y’ 에 관한 식은 아래와 같이 바꿔쓸 수 있습니다.

이를 정리하면 다음과 같은 꼴로 만들 수 있고,

우리가 값을 알고 싶은 변수들은 a, b, c, d, e, f, g, h 이렇게 8 개이므로, (x, y) 와 그에 대응되는 (x’, y’) 쌍을 4개만 알고 있으면 projection matrix 를 구할 수 있습니다. 이를 구하기 위한 매트릭스는 아래와 같습니다.

남은 건 8×8 matrix 의 inverse matrix 를 구한 뒤 뒤 쪽의 매트릭스에 곱해주는 것 뿐이군요.

Implementation of Perspective projection

이제까지 Perspective Transform 을 위한 매트릭스에 대해 알아봤습니다. 이제는 실제 구현을 해보는 것만 남았네요. 위에서 알아봤듯이 Perspective matrix 를 구하려면 matrix multiplication 과 inverse 를 위한 인터페이스가 필요합니다.

matrix multiplication 의 경우 서로 곱할 수 있는 형식인지를 체크한 뒤 단순한 계산을 하면 되고, inverse 는 gauss elimination 을 이용 reduced row echelon form 으로 만들어주는 것을 통해 쉽게(?) 구해낼 수 있습니다.

위의 두 가지까지 구현했다면, 이제 warping 만을 구현하면 되겠습니다. 이 warping 은 크게 두가지 방법을 통해 구현할 수 있습니다.

forward mapping

forward mapping 은 말 그대로 src 의 x, y 좌표에 대하 dst 의 x’, y’ 를 계산 한 뒤 값을 채워주는 방식입니다. 간단히 pseudo code 로 표현하면 다음과 같이 표현할 수 있겠네요.

근데 막상 구현을 해놓고 보면 pixel 이 정수단위이기 때문에 아래와 같이 hole 이 발생하는 것을 확인할 수 있습니다.

backward mapping

위에서 얘기한 hole 을 방지하기 위한 방법 중 하나로 backward warping 이란 것이 있습니다. forward warping 에서 src 의 좌표를 기준으로 dst 의 좌표를 계산했다면, backward warping 에서는 dst 의 좌표를 기준으로 src 의 좌표를 계산하게 됩니다.
간단하게 pseudo code 로 표현하면 아래와 같이 되겠습니다.

간단히 코드만 봐도 예상할 수 있겠지만 backward_warping 을 해주게 되면 hole 은 확실하게 없앨 수 있습니다. 결과 이미지는 아래와 같은데, 아주 깔끔한 결과가 나오지는 않았습니다.

forward (or backward) warping with interpolation

forward warping 을 하게 되면 hole 이 생기게 되고, 단순한 backward warping 을 하게 되면 이미지의 화질 저하가 발생하게 되는데, interpolation 을 사용하게 되면 이를 조금 더 개선할 수 있습니다.

전 linear-interpolation 을 사용해보았는데, 설명하기는 복잡하니 관심있으신 분은 저 아래 첨부할 소스를 참고해보시면 좋겠습니다. 결과는 아래와 같이 나옵니다.

우선 interpolation 을 이용한 forward warping 입니다. 복잡하게 하기는 귀찮고 해서 대강 구현했더니, hole 이 줄기는 했지만 여전히 존재하고 있습니다.

다음은 backward warping 에 linear interpolation 을 적용한 결과입니다. hole 도 없고, 보기에 상당히 괜찮아진 것을 확인할 수 있습니다.

소스코드:
https://github.com/Tee0125/snippet/tree/master/perspective_projection
참고자료:
http://en.wikipedia.org/wiki/Perspective_%28graphical%29
http://en.wikipedia.org/wiki/Gaussian_elimination
p.s) 부동 소숫점 연산에서 x – x/x*x = 0 이라는 것이 보장되질 않더군요. 코드 한 줄 줄일려다가 디버깅을 30분동안 해야했습니다. -_ㅜ

에스프레소!!

더 맛있는 커피를 마시기 위해 또 몇 가지를 지르고 말았습니다. 지른 품목들은 사진에 보이는 순서대로 로스팅된 커피, 브리카 모카 포트, 커피 그라인더, 브리타 온탭 정수기 가 되겠습니다. ㅋㅋ

집에 정수기가 없다보니 얼음을 얼린다거나 커피, 홍차등을 끓일 때 끓였다 식힌 수돗물을 사용했었는데 언제 필요할 지 모르는 물을 미리미리 충분히 준비해둘 수도 없고 -_-; 끓였다 식힌 물도 며칠동안 놔두지 않으면 염소 냄새가 없어지지를 않더라구요. 오랫동안 사용하지 않으면 물 때가 끼기도 하고… (완전 계륵이죠 -_-)

일본 여행 때 수돗꼭지에 끼는 형태의 브리타 온탭 정수기를 보고 딱 이거다 싶어서 인터넷을 뒤져봤더니 한국에서도 살 수 있다는 사실을 알게됐습니다. (일본에서 사는게 조금 더 쌌습니다.) 이틀 정도 심각하게 고민한 끝에 확 질러버렸습니다. 설거지를 할 때도 정수된 물을 사용하면 필터 낭비가 아닐까 하는 걱정이 있었지만, 회색 레버를 이용해서 bypass 설정을 할 수 있기 때문에 저 걱정은 기우였다는 걸 알게됐습니다. 사용하기 시작한 지는 한 2주쯤 됐고, 효과는 좋은 것 같습니다. 만족 ㅋㅋ 필터는 3~4달에 한 번 정도 갈아주면 되고, 필터 교환 시기가 되면 위 쪽에 빨간 불이 들어온다고 합니다. 평상시에는 녹색 불~

그리고 그라인더는 사실 제가 지른 게 아니고 어머님께서 호주에 여행갔다 오시면서 선물로 사오신거에요. 물건너온 녀석이라 전원 코드가 달라서 아래 사진에서 처럼 유니버설 트래블러 어댑터와 함께 사용하고 있습니다. –; 호주는 전원이 230v 에 50hz 이고 한국은 220v 에 60hz 라 모터를 사용하는 제품의 경우 약간 문제가 있을 수 있다는 생각이 들지만 커피를 가는데는 채 20초가 걸리지 않기 때문에 그냥 써도 될거 같습니다. 히힛!

그라인더 몸체에 보면 갈리는 정도를 조절할 수 있는 레버가 있고, 제가 원하는 정도에 레버를 맞춘뒤 동그란 버튼을 누르면 설정에 맞춰서 가는 시간을 알아서 조절해줍니다. 얼마 전까지는 그라인더가 없었기 때문에 갈려있는 커피를 주문했었는데 이젠 그럴 필요가 없기 때문에 -_-v 과감하게 빈 상태의 원두도 질러줬습니다. (조금 남아있던 갈려진 커피는 모카포트 세척용으로 사용!)

마지막으로 브리카 모카포트!! 모카포트를 보면 2만원 대의 싼 제품부터 10만원대의 비싼 제품까지 있는데 … ‘이젠 나도 제대로 된 에스프레소를 즐겨보는거야!!’ 란 생각으로 젤 비싼 브리카를 질렀습니다. 알라딘에서 기본 할인 10% 에 추가로 7% 할인 쿠폰을 제공하길래 거기 홀려서 흑흑;;

그저께 배송을 받고 어제부터 신나게 에스프레소 질을 하고 있는데 이거 생각보다 중독성이 있습니다. 2001년도에 처음 에스프레소를 시켰을 때 그 쪼만한 잔에 놀랐고, 그 쓴 맛에 당황하며 다방 커피를 만들어먹었던 기억이 있는데 제 입맛이 확실히 변한 것 같네요. 그 땐 아메리카노 같은 블랙 커피도 못먹었으니 어쩜 당연한 결과였을 수도…-_-;;

하여튼 시큼한 맛과 어느정도 쓴 맛에 굉장한 향기… 대게 맘에 들어요. 더 맛있는 커피를 먹기 위해 한동안 술을 줄여야겠습니다. (줄어든 술값으로 커피 관련 도구들 값들을 메꾸려는 얕은 계략!!) 맛이 궁금한 분은 맛난 걸 사들고 저희집으로 찾아오시면 되겠습니다. ㅋㅋ

스티브 잡스 인터뷰…

키노트를 볼 때마다 혹은 인터뷰 내용들을 볼 때마다 느끼는 사실이지만 스티브 잡스는 참 말을 잘 하는 것 같아요. Mac World 를 읽다가 인상적인 내용이 있어서 살짝 가져와서 번역해봅니다. 🙂

원문:
Is Apple’s goal to overtake the PC in market share? Jobs said, “Our goal is to make the best personal computers in the world and make products we are proud to sell and recommend to our family and friends. We want to do that at the lowest prices we can.
“But there’s some stuff in our industry that we wouldn’t be proud to ship. And we just can’t do it. We can’t ship junk,” said Jobs. “There are thresholds we can’t cross because of who we are. And we think that there’s a very significant slice of the [market] that wants that too. You’ll find that our products are not premium priced. You price out our competitors’ products, and add features that actually make them useful, and they’re the same or actually more expensive. We don’t offer stripped-down, lousy products.”
해석:
“애플의 목적은 PC 보다 많은 마켓쉐어를 가지는 것인가요?”
잡스:
“우리는 세계 최고의 PC 를 만드는 것이 목적입니다. 우리가 자랑스럽게 팔 수 있고, 우리 가족이나 친구에게 자랑스럽게 추천할 수 있는 그런 제품을 말이죠. 우린 가능한한 싼 가격으로 이런 제품을 제공하고 싶습니다.
하지만 우리가 만드는 것들 모두가 자랑스럽게 팔 수 있을만한 것은 아니었습니다. 그래도 우린 쓰레기를 팔 수 없었습니다. 우리는 애플이거든요. 시장도 우리가 그러길 바라고 있다고 확신할 수 있습니다.
우리 제품을 보셨으면 알겠지만 우리는 비싼 가격으로 제품을 내놓지 않습니다. 게다가 누구처럼 경쟁 제품의 가격을 알아보고, 그 제품과 비슷한 프로그램에 약간의 유용한 기능을 더한 뒤 더 비싼 가격으로 파는 그런 야비한 짓도 하지 않구요.”

출처: http://www.macworld.com/news/2007/08/07/macevent/index.php
저 인터뷰 중 “우리 가족이나 친구에게 자랑스럽게 추천할 수 있는 제품” 이 말이 참 맘에 와 닿는 것 같습니다.
그냥 새벽까지 안자고 웹서핑질을 하다가 오랫만에 번역해보고 싶은 게 있어서 =3=33 (중간중간 그냥 의미만 살려서 의역해버린 부분이 좀 있습니다. 꼬투리 잡진 말아주세요 -_-)

이쁜 아이콘 배포 사이트~

  1. Silk Icons: http://www.famfamfam.com/lab/icons/silk/
  2. Intefrace Lift: http://interfacelift.com/

Silk IconCreative Commons Attribution 2.5 License 로 배포되고 있는 16×16 아이콘으로 애플리케이션의 툴바라거나 웹페이지 버튼으로 쓰기 적당한 아이콘들 이다. 사용료는 $0.0 지만 굉장히 높은 퀄리티를 가지고 있기 때문에 활용도는 상당히 높을 것 같다.
그리고 Interface Lift 는 Mac OS X 와 MS Windows 용 고품질 아이콘들을 구할 수 있는 곳! Mac 용 VLC 아이콘이나 Mplayer 아이콘을 인터페이스 리프트에서 구한 아이콘으로 대체해버렸는데 굉장히 만족스럽다. 히힛

YUVplayer for MS Windows

지난 이틀간 작업한 내 YUVPlayer for windows~! MFC + OpenGL 기반으로 작성되었고, 정말 아무 문제 없이 사용할 수 있을만큼 완성도 높게 작업해보기는 처음이 아닐까 싶다. (CUI 기반으로는 공개를 하고 있지는 않았지만 혼자 유용하게 쓰는게 몇 가지 있는데… GUI 기반으로는 정말 처음인 것 같다.)

단축키를 통해 모든 액션을 취할 수 있고, 드래그앤 드롭을 통한 파일 오픈 또한 가능하다. 게다가 _lseeki64 같이 64bit offset 을 사용하는 시스템 콜을 사용하고 있기 때문에 2GB 를 넘어가는 파일들도 문제 없이 플레이가 가능하다. (31GB 짜리 파일도 문제 없이 플레이가 가능한 것을 확인했음.)

위 스크린 샷은 기본적인 플레이 화면! CBitmapButton 을 통해 이쁜 플레이어 버튼을 만들었고, 여러가지 편법을 통해 –;; 사이즈가 조절되더라도 저 레이아웃이 그대로 유지되도록 만들었다.

File 메뉴에서는 YUV file 을 열거나 원하는 프레임으로 가는 등의 동작이 가능하다.

File 메뉴에 있는 Go 버튼을 누르거나 단축키 ‘g’ 를 누르게 되면 위와 같은 창이 뜨게 되는데… frame no 필드에는 기본적으로 현재 플레이되고 있는 프레임 번호가 입력되어 있도록 만들었고, 저기에 원하는 프레임 번호를 입력하게 되면 바로 점프가 가능하다.

이건 마우스 오른쪽 버튼을 누르면 나오게 되는 컨텍스트 메뉴! 현재 보고 있는 프레임을 파일로 저장할 수 있는 메뉴들을 제공하고 있다. Luminance 성분은 raw 포멧, YUV* 은 YUV 포멧, RGB 는 32bit BMP 포멧으로 저장된다.


yuv file 은 header 가 없이 데이타만 주루룩 들어가 있는 형태이기 때문에 size 를 알 수가 없으므로 직접 사이즈를 지정해줘야 하는데, 기본 사이즈는 내가 제일 많이 사용하게 될 듯한 CIF (352×288) 사이즈로 지정해두었고, s(SD: 720×480), h(HD: 1920×1080), c(CIF: 352×288), q(QCIF: 176×144), u(Custum) 등의 단축키를 통해 다른 사이즈로도 쉽게 변경할 수 있도록 만들었다.

위에 나열해놓은 기본 사이즈가 아니더라도 Custum Size 를 입력할 수 있는 메뉴 또한 준비되어 있다.

color format 또한 yuv444, yuv422, yuv420, y(luminance only) 등의 포멧을 지원한다.

2배 확대, 1/2 축소 등의 기능까지도 제공 -_-v

학부 시절 ‘게임 프로그래밍’ 과목 수강 이후 오랫만에 MFC + openGL 프로그래밍이다보니 가끔 헤매기도 했지만, 잘 설계된 openGL 덕에 기능을 추가하는 것이 쉽게 쉽게 이루어지지 않았나 싶다.

툴도 Visual Studio 2005 로 갈아탔는데, 확실히 여러 면으로 IDE 가 진보했음을 느낄 수 있었다. 다만 Visual Stuido 2005 이거이거 꽤 무거운거 같다. Class Wizard 가 없어졌기 때문에 조금 혼란스럽기도 하지만 뭐 Code Definition Window 등 새로 추가된 기능들은 이런 점을 보완해주고도 남는 듯…

MFC 는 (지금도 잘 모르지만) 거의 초보였는데 요번 프로그램을 통해 좀 자신감이 붙는 것 같다. 원하는 기능을 구현하기 위해 어떤 검색어를 넣으면 될 지에 대한 노하우도 좀 생기는 것 같고, 하여튼 지난 이틀간 이 프로그램을 만들면서 참 재밌었던 것 같다.

이제 남은건 히스토그램을 그려주는 기능 뿐인가!!

다운로드:

Change Log:

2007년 7월 15일

  1. uyuv 포멧 지원 추가
  2. 소스 공개

2008년 8월 2일

  1. ::GetDC(hWnd) 후 ::ReleaseDC(hWnd,dc) 를 호출 하지 않아서 생기는 메모리 릭 제거
  2. gdTexImage2D 를 반복 호출해서 생기게 되는 메모리 릭 제거

p.s) Visual Studio 에서 만든 프로젝트는 버젼 관리 시스템등에 어떻게 넣어야할지 모르겠다. 하여튼 코드를 조금 더 정리하고, sourceforge 등에 오픈소스 프로젝트로 올려볼 생각!!

OpenGL: texture vs glDrawPixels

openGL 을 사용해서 2D 이미지 데이타를 화면에 뿌려주는 방법은 대강 다음과 같이 세가지로 분류할 수 있는 것 같다.

  1. glBegin(GL_POINTS); glColor3i(…);glVertex3d(x0,y0,0); …반복; glEnd();
  2. texture 로 올려주고, 해당 texture 가 입혀진 quad 을 그려줌
  3. glDrawPixels 를 이용

첫번째 방법이야 그냥 저렇게도 가능하다는거지 실제 저렇게 사용할 일은 없다고 생각되고, 실제 빠르게 화면에 2D 이미지를 그려주기 위해서는 2번째 방법이나 3번째 방법을 사용해야할텐데, 저 중에 어떤 걸 사용하는게 더 좋은 방법인지 확신이 들질 않는다.

우선 화면이 확대되었을 때 texture 를 사용할 경우 GL_LINEAR 등의 기본으로 제공되는 interpolation method 들이 있기 때문에 (약간 Blur 된 결과일지는 모르지만) 더 좋은 품질의 이미지를 얻을 수 있겠고, 화면이 다시 그려질 일이 있을 때 texture 데이타가 다시 전송될 필요가 없다는 장점이 있는 듯 싶지만, (texture 로 등록할 때 이미지 데이타는 비디오 메모리로 옮겨진다.) width 나 height 가 2^x 형태로 표현되어야 한다는 제약이 있다. 이게 만약 이미지가 크지 않다면 큰 문제가 되지 않겠지만 만약 HD Sequence 라면? 1920×1080 을 표현하기 위해 2048×2048 = 4MB 를 사용해야 하므로 반 정도의 공간이 낭비될 수밖에 없다.

glDrawPixels 는 다시 화면을 그려줘야할 때마다 이미지 데이타를 메인메모리->비디오메모리 로 복사해줘야 하는 문제가 있지만 만약 동영상 플레이어등을 만들 때 처럼 빠르게 화면이 전환되는 경우라면 이는 큰 문제가 되지 않을 듯 싶기는 하다. 물론 화면이 멈춰있는 상태라면 얘기가 다를 지 모르겠다. 또 이미지를 실제 크기보다 더 크게 표현할 경우 glPixelZoom 을 이용해 간단히 구현할 수 있지만 실제로는 픽셀 크기만 커지는 효과이지 interpolation 은 일어나지 않으므로 화질은 texture 를 사용할 때에 비해 떨어진다고 할 수 있을 듯…

뭐 하튼 뭘 사용하는게 더 좋은건지 인터넷을 열심히 찾아봤지만 뭐가 더 좋은지에 대한 정확한 답은 찾을 수가 없다. -_-!

p.s) yuv2rgb 변환 같은 것은 cg 를 이용해서 처리할 수 있는 것 같은데… 이 경우 texture 를 사용해야지만 가능 한 듯…

openGL 에 이미 4×4 matrix multiplication 은 구현되어 있으므로 color_matrix 를 사용해서 yuv2rgb 변환을 빨리할 수 있지 않을까 하는 생각도 해봤지만 실제 결과는 참담…