'Computer Vision'에 해당되는 글 2건

  1. 2015.09.25 카메라 이동 속도를 구하기 위한 옵티컬 플로우 3
  2. 2013.04.13 [자작]템플릿 패턴 매칭 테스트
Computer Vision2015. 9. 25. 20:05


옵티컬 플로우는 컴퓨터비전을 공부하다 보면 꼭 나오는 주제입니다. 원리와 수식은 위키피디아, 블로그, openCV API에 많이 나와있으니 글 하단에
참고사이트로 대신하고, 이 포스팅에서는 제가 헷갈렸던 이야기와 몇 가지 개념에 대해 써보겠습니다.


옵티컬 플로우 또는 광류라고 하는 이 알고리즘은 간단히 말하면 차영상의 진화버전이라고 할 수 있겠습니다. 이전 프레임과 현재 프레임의 차이에 관심을 둔다는 점에서요.


저는 옵티컬 플로우를 처음에 아래 그림처럼 접했었습니다. 제 선배가 옵티컬 플로우를 사용해서 논문을 쓰는걸 봤는데 아래 그림과 같은 방식으로 사용하시더라구요.




이전 프레임에서 강인해 보이는(다음 프레임에서도 추출될 만한) 특징점 추출 후 현재 프레임에서 같은 특징점을 찾아 얼만큼 위치변화가 있었는지 보는 방식입니다.


여기서 짚고 넘어가야할 점은, 특징점의 분포가 움직이는 물체 부분에 밀집되어 있다는 점입니다. 위 그림처럼 카메라가 고정되어있고 자동차가 움직인다면 특징점은 차도에 많이 생기겠죠.


이렇다 보니 옵티컬 플로우를 객체 위치 인식 및 추적용으로 생각하시는 분들이 많은 것 같아요.(실제로 그렇게 사용하기도 합니다.)


하지만 제 생각에는 옵티컬 플로우는 물체가 어떻게 움직이고 있는지 판단할 때 가장 좋은 알고리즘이 아닐까 싶습니다. 


여기서 잠깐, Lucas-Kanade(LK), Horn-Schunk(HS)라는 키워드에 대해 짚고 넘어가겠습니다.


이것도 많이 헤매게 된 부분인데요, AR.Drone 논문에서 옵티컬 플로우를 LK와 HS를 모두 사용했다고 나오길래, 옵티컬 플로우는 크게 두 가지 방법이 있는 줄 알았습니다. openCV에는 아예 대놓고 calcOpticalFlowPyrLK()라는 함수가 있고 API를 봐도 루카스 카나데 방법을 사용한다고 써놨습니다. 근데 HS방법은 아무리 검색을 해봐도 안나와서 이상타 싶었는데 HS는 옵티컬 플로우를 어떻게 해석하는지에 중점을 두고 연구한 사람들이더라구요. (아래 참고사이트에 책 내용이 잘 나와 있다는 사이트를 참고하세요~)


위 자동차 그림처럼 특징점의 위치가 고르지 않은 상황에서는 HS방법을 쓰기 힘들 것 같네요.



            



이렇게 되어있는 경우 잘 들어맞을 것 같습니다.


객체와 배경이 함께 움직인다면 배경 부분까지 옵티컬 플로우가 만들어질 겁니다. 배경이 움직인다는건 다시 말해 카메라가 움직인다는 걸로도 볼 수 있기 때문에 배경의 속도는 카메라의 속도로 이어집니다.


이런 생각에 착안해 화면 전체의 옵티컬 플로우를 구하기 위해 찾아보았습니다.


아래의 제가 찍은 옵티컬플로우 동영상과 같이, 윙윙이에도 이런 방식을 적용했습니다.





openCV로 구현했구요, 프레임을 100개의 정사각형 블럭으로 나누고 블럭 중앙을 특징점으로 정한다음에 다음 프레임에서 특징점을 찾는 방식입니다.


노이즈가 심한거는 옵티컬 플로우 함수의 파라미터를 조정해서 개선했구요, 말도 안되게 튀는 노이즈는 if문으로 제거했습니다.


원래는 RANSAC을 이용해서 outlier 필터링을 하려고 했는데 각 벡터들을 평균해보니 꽤 쓸만한 값이 나와서 일단 그대로 사용하는 중입니다.


함수는 


calcOpticalFlowPyrLK(frame_prev, frame_gray, featurePrev, featureNext, isFound, err, winSize, 3, termcrit, 0, 0.01);


이렇게 사용중입니다.


frame_prev : 이전 프레임(8비트 단일 채널)

frame_gray : 현재 프레임(8비트 단일 채널)

featurePrev : 이전 프레임의 특징점 좌표들(vector<Point2f>)

featureNext : 현재 프레임의 특징점 좌표들(vector<Point2f>) - 함수 내부에서 만들어서 출력해줌(길이는 featurePrev와 동일)

isFound : 특징점을 찾는데 성공했는지 배열로 저장(길이는 featurePrev와 동일)

err : 이전 특징점과 현재 특징점간의 거리를 배열에 저장((길이는 featurePrev와 동일)

winsize : LK방법이므로 지역적으로 찾기위한 윈도우 크기(Size)

3 : 피라미드 최대 계층 개수

termcrit : 종료 조건(TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03); 이렇게 사용중)

0.01 : 최소 고유값


여기서 성능에 가장 영향을 많이 미치는 부분은 윈도우 크기와 피라미드 최대 계층 개수였습니다. 윈도우 크기를 늘리거나 계층 수를 늘리면 노이즈가 적어지고 성능이 좋아지지만 처리 속도가 느려져 실시간 피드백용으로는 적합하지 않았습니다.


위 동영상의 성능과 보정, 융합 결과는 다음 포스팅에서 다루기로 하고 오늘은 여기까지~!




참고 사이트 및 문헌

OpenCV-optical flow ( http://docs.opencv.org/master/d7/d8b/tutorial_py_lucas_kanade.html#gsc.tab=0 )

책의 내용과 이론 설명이 잘 되어있는 사이트( http://lueseypid.tistory.com/98 )

Determining optical flow - HornSchunk ( http://dspace.mit.edu/bitstream/handle/1721.1/6337/AIM-572.pdf?sequence=2 )

The navigation and control technology inside the ar. drone micro uav http://cas.ensmp.fr/~petit/papers/ifac11/PJB.pdf )






'Computer Vision' 카테고리의 다른 글

[자작]템플릿 패턴 매칭 테스트  (0) 2013.04.13
Posted by 너를위한노래
Computer Vision2013. 4. 13. 14:52

캠으로 찍고 있는 동영상에서 내가 가지고 있는 bmp파일과 비슷한 부분을 어떻게 찾아내느냐...

 

뭐 템플릿 매칭에 대한 많은 논문과 알려진 기술들이 많지만.. 그리고 OpenCV에 쉽게 구현까지 되어있지만..

 

이미 알려진 기술을 사용하는 법도 물론 중요하지만 제가 아직 학생이라 그런지 알고리즘을 배우거나 실제 구현하는거는 나쁘지 않다고 봅니다.

 

그렇다고 SURF나 SIFT같은 기술을 그대로 구현하는건 제가 나가는 영상처리 대회의 취지하고도 안맞고 해서 다른 알고리즘을 계속 생각하고 있었는데.. 문득 떠오른게 이 패턴매칭..!!

 

될지 안될지 긴가민가했는데 일단 해보고 알 일이니까 (실패해도 좋은 경험이니까) 일단 해보기로 했습니다

 

 

캠으로 계속 찍고 있는 사진에서 이 그림을 찾을겁니다 (제가 자주가는 미용실 마크입니다...ㅋ) (100x100 입니다)

 

일단 저 노란부분(y=50)의 픽셀만 뽑아서 상승, 하강, 유지의 패턴을 추출해 보겠습니다.

 

  (이하 빨간패턴)

 

흰부분은 높고 검은부분은 낮게 나오죠?

 

그리고 저 빨간 점들은 제가 만든 알고리즘으로 추출한 패턴들입니다.

 

이제 이 패턴을 캠 영상하고 비교를 해야겠죠?

 

 

(이하 초록패턴)

원본 영상의 어느 한 줄의 픽셀만 뽑아서 같은 알고리즘을 통과시킨 그림입니다. 마찬가지로 초록 점이 추출된 패턴들이구요

 

초록패턴 중간에 빨간패턴과 비슷한게 보이시죠? 이 부분을 찾는게 제 아이디어 입니다 ㅋ

 

프로토타입으로 만든 결과를 보시면 

 

머리가 개털처럼 나왔네요.. 눈도 퀭한게.. ㅠ  암튼...

 

정확도가 좀 떨어지는데 가로방향 한줄로만 해서 그런거 같아요

 

각 줄에 매칭되는 범위를 조금 늘리고 가로방향 3줄, 세로방향 3줄로 해서 총 6개의 매칭 분포가 많은 부분을 찾으면 좀 더 정확도가 올라갈거 같아요

 

그리고 제 아이디어의 단점이 회전시키면 못찾는건데 이것도 좀 연구를 해봐야겠네요

 

그래도 가능성이 어느정도 보입니다 패턴의 매칭이라서 픽셀단위 매칭처럼 오래걸리지도 않고..

 

일단 해봐야 알 일이죠 될지 안될지는.. ㅋ  

 

 

- 7월 11일 추가

 

가로세로 각각 3줄씩 매칭을 해봤는데 어느 한 부분도 매칭이 안되더군요.. 매칭을 허용하는 범위를 대폭 늘렸더니 쓸데없는거까지 잡고..

 

그래서 최대한 범위를 적당히 수정해봤는데 원하는 부분도 잘 찾지만 다른부분도 잘 찾아서 문제.. ㅋ

 

과거 프레임 몇 개를 저장해두고 많이 나오는 부분을 찾으려고도 해봤지만 실패.. ㅋ

 

결국 대회는 다른 팀원이 구현한 SURF로 나갔네요.. 하지만 여러 가능성을 보았으므로 나쁘지 않은 시도였습니다.ㅋ



 - 14년 3월 6일 추가


지난 글을 보다 문득 든 생각이.. 복잡한 조건문으로 도배하지 않고 1차미분, 2차미분을 사용해서 그래프의 극값을 구할 수 있겠단 생각이 드네요.


이미 극값을 특징점으로 이용하는 알고리즘을 어디선가 본거 같긴 하지만.. 단독으로 사용할만 한건 아닌거 같네요.. 다른 특징점과 같이 사용하면 좋을 것 같다는 생각을 해봅니다.



Posted by 너를위한노래