Archive for the 'School' Category

정태영

하는거 없이 바쁜 척 하느라 블로그가 썰렁하게 만들어놓고 있습니다.

크리스마스 쯤 해서 석사 마지막 수업의 과제들을 제출했고, 4.0 이란 무난한 평점과 함께 학기를 마무리 했습니다. 지난 학기에는 H.264 / MVC Project 와 관련이 되어 있기도 했고, HCI 수업을 통해 공부한 것도 있고 해서 3D geometry 쪽으로 많이 살펴볼 수 있었던 것 같습니다. 관련해서 재밌는 내용들도 많았고, 정리해두고 싶은 내용도 많기 때문에 시간을 내서 곧 몇 가지를 포스팅해볼 생각입니다.

어쨌거나 석사를 시작한지 벌써 1년이 지났지만 연구주제도 아직 못잡고 갈팡질팡하고 있네요. 비디오 코덱에 관심이 없는 것은 아니지만 정말 해보고 싶은 연구들은 너무나도 손이 많이 가기에 혼자서 선뜻 시작해볼 수가 고, 다른 것들은 … 노코멘트 -_-; 게으름이 가장 큰 적이긴 하지만…

하여튼 12학점/12학점 해서 필수 졸업 학점인 24학점을 이미 채웠으니 남은 일 년간은 게임도 줄이고 잠도 줄이고 공부를 하는데 시간을 많이 할애해봐야겠습니다. 꺄홋!

화이팅!

정태영

5시간쯤 후에 기말고사를 봐야하는데다가 34시간 후에는 텀프로젝트 데모 시연을 해야하는 관계로 밤을 세고 있습니다. 사실 제가 하려는 텀 프로젝트와 관련된 이론은 이미 이주 전에 이해해 놓은 상태였는데도 불구하고 코드 작성은 발표 전 48시간동안 이루어지게 되는군요. 결국 요번 텀프로젝트도 학부 졸업 프로젝트처럼 날림으로 -_-;;;


위 스크린샷이 지금 작업 중인 일부 샷입니다. vector 를 눈에 보이게 표시하려고 했는데, 범용 그래픽 api 를 사용하지 않고 있어서 line 을 그린다거나 특정 각도만큼 돌아가있는 사각형등을 보여주는게 쉽지 않아서 openGL 을 활용 간단한 gui 를 작성해버렸습니다.

이제 한 3~4일만 잘 버티면 방학이네요. 꺄하하 코딩하다 심심해서 뻘글 하나 날려봅니다. (풀타임 석사에게 방학이 무슨 의미려냐만은 ㅠ_ㅠ)

p.s) 그나저나 os x 이 업데이트 되면서 (10.4) 가짜로 볼드를 만들어내는 기능이 들어간 것 같네요. 그다지 이쁘진 않지만;;

정태영

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

정태영

며칠 전 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 같은 라이브러리를 설계하신 분들은 상상하기 힘들 정도로 똑똑한 것 같아요.

소스:
http://trac.unfix.net/browser/snippet/rotation_3d

정태영

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 로 표현하면 다음과 같이 표현할 수 있겠네요.

for( y = 0 ; y < height ; y++ ){ for( x = 0 ; x < width ; x++ ){ x' = (ax+by+c) / (gx+hy+1); y' = (dx+ey+f) / (gx+hy+1);   dst[y'][x'] = src[y][x]; } }

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

backward mapping

위에서 얘기한 hole 을 방지하기 위한 방법 중 하나로 backward warping 이란 것이 있습니다. forward warping 에서 src 의 좌표를 기준으로 dst 의 좌표를 계산했다면, backward warping 에서는 dst 의 좌표를 기준으로 src 의 좌표를 계산하게 됩니다.

간단하게 pseudo code 로 표현하면 아래와 같이 되겠습니다.

for( y' = 0 ; y' < height ; y'++ ){ for( x' = 0 ; x' < width ; x'++ ){ x = (ax'+by'+c) / (gx'+hy'+1); y = (dx'+ey'+f) / (gx'+hy'+1);   dst[y'][x'] = src[y][x]; } }

간단히 코드만 봐도 예상할 수 있겠지만 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 도 없고, 보기에 상당히 괜찮아진 것을 확인할 수 있습니다.

소스코드:
http://trac.unfix.net/browser/snippet/image_projection/

참고자료:
http://en.wikipedia.org/wiki/Perspective_%28graphical%29
http://en.wikipedia.org/wiki/Gaussian_elimination

p.s) 부동 소숫점 연산에서 x - x/x*x = 0 이라는 것이 보장되질 않더군요. 코드 한 줄 줄일려다가 디버깅을 30분동안 해야했습니다. -_ㅜ

정태영

요번 주 월요일에 개강을 했습니다. 홍대는 대게 9월에 개강을 하는데 그에 비해 한양대는 일주일이나 빠르네요. 홍대는 한 학기가 15주이고 한양대는 16주인 것과 연관이 있을지도 모르겠습니다. (홍익대학교 전자전기 공학부는 중간고사, 기말고사 기간이 따로 없고 수업 후 저녁 시간에 시험을 봤기 때문에 학기가 짧다고 수업까지 적지는 않습니다. 단 컴퓨터 공학과는 시험기간이 따로 있었기 때문에 예외 -_-; )

예전에 얘기했듯이 요번 학기엔 내장형 시스템, 임베디드 소프트웨어, 인간 컴퓨터 상호작용, 컴퓨터 특론 이렇게 네 과목을 신청했습니다. 첫 주가 지났으니 한 학기 동안 수업할 내용에 대한 개론들이 전부 있었는데 몇 과목은 제가 생각했던 내용과 많이 다르더라구요.

인간 컴퓨터 상호작용을 영어로 옮기면 Human Computer Interaction 이고 제가 관련해서 이전에 봤었던 내용은 대부분 컴퓨터 인터페이스와 관련된 것들이었습니다. 특히나 UI (User Interface) 관련된 것들을 많이 있었기 때문에 당연히 그런 것과 관련이 있는 과목일거라 생각했는데 제가 알고 있는 HCI 는 매우 한정된 부분이었네요.

하여튼 이 과목은 3D 좌표계나 렌더링과 관련된 내용으로 시작되서 Lighting (이것도 렌더링에 포함시켜야할 지도 모르겠네요.), Stereo vision 과 관련된 내용을 본 뒤 Computer Vision 쪽을 살펴보게 될 것 같습니다. 렌더링은 Output 을 위한 부분이고, Computer Vision 쪽은 Input 과 관련된 내용이니 인간과 컴퓨터 사이의 I/O (Input/Output) 를 얘기하기 위해 Rendering 과 Computer Vision 을 살펴보는 것이 전혀 어색하지 않네요.

그런데 쉬어가기 위한 과목으로 신청했던 ‘컴퓨터 특론’ 이 ‘Pattern Recognition’ 과 관련된 과목이어서 충격입니다. -_-; 특론이라고 하면 대게 그냥 널널하게 앉아서 시간만 떼우면 대강 학점이 나오는 그런 과목으로 알고 있었는데 뒤통수를 망치로 얻어맞은 기분이라고나 할까요. -_-; 과제까지 많이 내주겠다고 합니다.

결국 ARM 과 관련된 과목이 2과목, Computer Vision 과 관련해서 2 과목 되겠습니다. 왠만하면 요번학기에 수업을 모두 끝낼 예정이고, 이 외에 딱히 듣고 싶은 과목이 있는 건 아니기 때문에 좀 힘들거 같다는 생각도 들지만 왠만하면 드랍하지 않고 들을 생각입니다.

Computer Vision 은 제가 전공해보고 싶었던 분야이기도 했고, 여러가지 이유로(사실은 자신이 없어서) 포기했던 분야기도 한데 제 의도와는 상관없이 다시 만나게 되버렸네요. 어찌보면 굉장히 힘든 학기가 될 수도 있겠지만 나름 남는게 많은 학기가 될지도 모르겠다는 생각이 드네요.

두근두근…

정태영

하늘도 개강을 슬퍼하셔서 눈물을 흘리셨고, 덕분에 아침부터 쫄딱 젖어서 연구실에 도착했다. -_-; 분명히 집에서 나갈때 바라본 하늘은 너무나 화창했는데…

요번 학기에 나는 컴퓨터 특론, 임베디드 시스템, 내장형 시스템, 인간-컴퓨터 상호작용 (HCI 관련인 듯) 이렇게 네 과목을 신청했고 오늘 그 중 하나인 내장형 시스템 수업이 있었다. 첫 날부터 한 시간 반이나 강의를 하셨지만 이상하게도 하나도 지루하지가 않았다.

컴퓨터 아키텍쳐와 관련된 수업은 언제나 날 설레게 만든다. 삼 년도 전에 들었던 컴퓨터 아키텍쳐 관련된 내용을 하나도 잊지 않고 있다는 사실에 너무나도 즐거웠고, 파이프라이닝, 하버드 아키텍쳐, 수퍼 스케일러 등등 예전에 관심있게 찾아봤던 내용들로 수업이 진행되니 오랫만에 가슴이 두근거린다.

내일 있을 인간-컴퓨터 상호작용은 실라버스에 따르면 HCI(Human Computer Interaction) 관련인 듯 싶은데 이 쪽도 예전부터 한 번쯤 공부해보고 싶었던 만큼 약간의 흥분상태!! 하여튼 요번 학기는 아침 수업도 하나 밖에 없고, 신청한 과목들이 나름 재미있을 것 같기도 해서 조금 기대된다. 꺄아! 어디 한번 즐겨보자아 캬캭!!