Program/OPEN_CV

[Open CV] 객체추척과 모션벡터 _ 밀집 옵티컬플로우

사막여유 2022. 7. 3. 08:08
728x90

 

이전 강의에서 나온 파네백 알고리즘에 대해 알아본다.

 - 파네백 알고리즘 ( Farneback's algorithm )

    cv2.calcOpticalFlowFarnebak(...)
   Dense(밀집) points에 대한 이동 벡터 계산
   => 모든 픽셀에서 옵티컬플로우 벡터 계산

 

밀집 옵티컬플로우란?

입력영상 전체에서 움직임벡터를 계산하는 방법 

 


밀집 옵티컬플로우 계산 함수

flow = cv2.calcOpticalFlowFarneback (prev, next, flow, prev_scale, levels, winsize, iterations, poly_n, poly_sigma, flags)


prevImg: 이전 프레임 영상 ( 그레이스케일 영상 )

nextImg: 현재 프레임 영상 ( 그레이스케일 영상 )

flow : (출력) 계산된 옵티컬플로우. 행렬. 보통 None 입력
          np.ndarray.shape = ( h,w,2 ), dtype = np.float32

pyr_scale : 피라미드 영상을 만들 때 축소 비율 ( e.g. ) 0.5
                   ( 0.5 - 가로세로를 반씩 줄여가면서 피라미드를 만든다. )

levels : 피라미드 영상 개수. ( e.g. ) 3

winsize : 평균 윈도우 크기. ( e.g. ) 13, 15

iterations : 각 피라미드 레벨에서 알고리즘 반복 횟수. ( e.g. ) 10

poly_n : 다항식 확장을 위한 이웃 픽셀 크기. 보통 5 또는 7

poly_sigma : 가우시안 표준편차. 보통 poly_n = 5이면 1.1, poly_n = 7이면 1.5

flags : 0, cv2.OPTFLOW_USE_INITIAL_FLOW, cv2.OPTFLOW_FARNEBACK_


전일 배웠던 루카스 카나데 옵티컬 플로우에서는 Default 값을 제공해주고있어서

사용하기가 편리하지만 위 밀집 옵티컬 플로우 계산함수는 Default 값이 따로 없어 파라메타를

계산하고 넣어줘야해서 까다로운편에 속한다.

 

그럼 아래 소스 코드를 보고 사용법을 분석해보자

 

위 소스코드에서는 vtest.avi 파일을 사용하여 밀집 옵티컬플로우를 테스트한다.

vtest.avi 는 이전 강의에서도 많이 봤었던 동영상이다.

 

 

카메라는 고정되어있고 사람들이 움직일때 그 움직임을 감지할 수 있도록 한다.

 

이전 프레임과, 현재 프레임을 이용해서 OpticalFlow를 계산하는 것은 간단하지만

나온 옵티컬플로우를 어떻게 표시할 것인지에 대한 부분에서 소스코드가 길어질 수 있다. 

 

cap.read() 함수로 첫번째 프레임을 획득하고 Grayscale로 변환시켜준 뒤 

hsv 는 사람이 이동할 때 방향에따른 색상표현을 위해 생성.
( 0도는 빨간색, 180는 파란색 등으로 표현 )

 

그리고 while 루프 이후에는 실제 영상에서 프레임을 받아와서

OpticalFlowFarneback 을 계산해주는데 위에서 나왔던대로 많이 사용되는 값을 넣어 Flow 변수로 받아준다.

 

Flow에서 제일 마지막성분의 0번째가 모션벡터의 x성분, 1번째가 모션벡터 y성분인데

이를 cartToPolar ( 직각좌표계 -> 극좌표계 변환 )을 사용하여 해당 벡터의 크기와 방향정보를 리턴 받는다.

 

 

hsv[... , 0] = ang*180 / np.pi / 2

hsv[... , 1] = 255

hsv[... , 2] = cv2.noramlize( mag, None , 0 , 255, cv2.NORM_MINMAX )

hsv에서 s ( Stauation ) 에 해당하는 부분은 모두 255로 셋팅해주고
h ( Hue ) 에 해당하는 부분은 각도성분으로 셋팅해주고
v ( Value ) 에 해당하는 부분은 magnitude ( 광도 ) 를 정규화해서 사용한다.

그리고 나온 결과를 다시 BGR로 변환해서 보여준다.

 

결과를 보게되면 왼쪽으로 이동하는 사람은 파란색 오른쪽으로 이동하는 사람은 빨간색으로 표시되는 것을

볼 수 있다.

 

 

OpenCV 옵티컬플로우 클래스

OpenCV 사이트에 들어가보면 FarnebackOpticalFlow에 관한 설명이 나와있는데

여기서 나오는 함수 Default 값을 그대로 사용해도 된다.

728x90