Python/파이썬 OpenCV 공부

[파이썬 OpenCV] 영상의 모션 벡터 - 밀집 옵티컬플로우 - cv2.calcOpticalFlowFarneback

AI 꿈나무 2020. 10. 21. 16:42
반응형

밀집 옵티컬플로우 - 

 밀집 옵티컬 플로우는 모든 픽셀에 대해 옵티컬플로우를 계산하는 방법입니다.

 주로 파네백 알고리즘(Farneback's algorithm)을 이용하여 구현하게 됩니다.

 

출처 : OpenCV 튜토리얼

 

 옵티컬 플로우에 대한 설명은 여기 포스팅을 참조할 수 있습니다.

 

[파이썬 OpenCV] 영상의 모션 벡터 - 루카스 카나데 옵티컬 플로우 - cv2.calcOpticalFlowPyrLK

옵티컬플로우 - Optical flow  옵티컬플로우는 연속하는 두 프레임(영상)에서 카메라 또는 객체의 움직임에 의해 나타나는 객체의 이동 정보 패턴을 의미합니다.  픽셀이 어떻게 움직였는지를 화

deep-learning-study.tistory.com

밀집 옵티컬 플로우 계산 함수 - cv2.calcOpticalFlowFarneback

 입력 영상 전체에 대해서 움직임을 계산하는 함수입니다.

 

cv2.calcOpticalFlowFarneback(prev, next, flow, pyr_scale, levels, winsize, iterations, poly_n, poly_sigma, flags) -> flow

• prev, nex: 이전 영상과 현재 영상. 그레이스케일 영상.

• flow: (출력) 계산된 옵티컬플로우. np.ndarray. shape=(h, w, 2), dtype=np.float32.

• pyr_scale: 피라미드 영상을 만들 때 축소 비율. (e.g.) 0.5

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

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

• 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_GAUSSIAN.

 인자들이 디폴트값으로 지정되지 않아 자주 이용되는 값들을 직접 입력해 주어야 합니다.

 자주 이용되는 값들에 대한 정보는 OpenCV 홈페이지에서 확인할 수 있습니다.

 

파네백 옵티컬 플로우 계산 예제 코드

 예제 코드 출처 :  황선규 박사님 github홈페이지 sunkyoo.github.io/opencv4cvml/

 

def draw_flow(img, flow, step=16)
    h, w = img.shape[:2]
    y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2, -1).astype(int)
    fx, fy = flow[y, x].T
    lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
    lines = np.int32(lines + 0.5)
    
    # 입력 영상의 컬러 영상 변환
    vis = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    
    # 직선 그리기
    cv2.polylines(vis, lines, 0, (0, 255, 255), lineType=cv2.LINE_AA)
    
    for (x1, y1), (_x2, _y2) in lines:
        cv2.circle(vis, (x1, y1), 1, (0, 128, 255), -1, lineType=cv2.LINE_AA)
        
    return vis
    
ap = cv2.VideoCapture('vtest.avi')

if not cap.isOpened():
    print('Camera open failed!')
    sys.exit()

ret, frame1 = cap.read()

if not ret:
    print('frame read failed!')
    sys.exit()

gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY)

while True:
    ret, frame2 = cap.read()

    if not ret:
        print('frame read failed!')
        sys.exit()

    gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY)
    flow - cv2.calcOpticalFlowFarneback(gray1, gray2, None, 0.5, 3, 13, 3, 5, 1.1, 0)
    
    cv2.imshow('frame2', draw_flow(gray2, flow))
    if cv2.waitKey(20) == 27:
        break
        
    gray1 = gray2

cv2.destroyAllWindows()

 

 이처럼 사람들의 이동경로를 화살표로 표현할 수 있습니다.

 


OpenCV 튜토리얼과 황선규 박사님의 'OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝' 을 공부하면서 정리해 보았습니다.

docs.opencv.org/4.3.0/d4/dee/tutorial_optical_flow.html  

 

OpenCV: Optical Flow

Goal In this chapter, We will understand the concepts of optical flow and its estimation using Lucas-Kanade method. We will use functions like cv.calcOpticalFlowPyrLK() to track feature points in a video. We will create a dense optical flow field using the

docs.opencv.org

 

반응형