본문 바로가기
Python/OpenCV

[OpenCV] 광 흐름 탐지 - optical flow detection

by hotelshoe 2022. 1. 3.
반응형

OpenCV의 calcOpticalFlowPyrLK 함수를 활용한 광 흐름 탐지(optical flow)를 코드 작성을 통해 테스트 해보겠습니다.


소스코드

import numpy as np
import cv2 as cv

#--비디오 파일 경로
path = './vedio.mp4'
cap = cv.VideoCapture(path)
#-- ShiTomasi corner 탐지를 위한 매개변수
feature_params = dict( maxCorners = 100,
                       qualityLevel = 0.3,
                       minDistance = 7,
                       blockSize = 7 )
#-- lucas kanade optical flow를 위한 매개변수
lk_params = dict( winSize  = (15, 15),
                  maxLevel = 2,
                  criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
#-- 랜덤 색상 변수
color = np.random.randint(0, 255, (100, 3))
#-- 첫 프레임을 잡고 corner 를 찾기
ret, old_frame = cap.read()
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)
p0 = cv.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
#-- 마스크 이미지 생성
mask = np.zeros_like(old_frame)
while(1):
    ret, frame = cap.read()
    if not ret:
        print('No frames grabbed!')
        break
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    #-- optical flow 계산 
    p1, st, err = cv.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
    #-- 적절 지점 선택
    if p1 is not None:
        good_new = p1[st==1]
        good_old = p0[st==1]
    #-- 트랙 그리기
    for i, (new, old) in enumerate(zip(good_new, good_old)):
        a, b = new.ravel()
        c, d = old.ravel()
        mask = cv.line(mask, (int(a), int(b)), (int(c), int(d)), color[i].tolist(), 2)
        frame = cv.circle(frame, (int(a), int(b)), 5, color[i].tolist(), -1)
    img = cv.add(frame, mask)
    cv.imshow('frame', img)
    if cv.waitKey(27) & 0xFF == ord('q'):
        break
    #-- 이전 프레임과 포인트를 업데이트
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1, 1, 2)
cv.destroyAllWindows()

 


테스트

샘플 동영상에 적용시킨 모습

자동차 헤드라이트의 경로를 잘 인식하는 듯 하나 몇몇 잘 못 인식된 부분도 보인다.

 

 

국내 야간 도로에서 촬영한 샘플 동영상 두 번째에 적용시킨 모습

이 역시도 간판의 불빛이라든지 자동차 헤드라이트 등을 잘 인식하는 듯 하나 몇몇 잘 못된 인식을 볼 수 있다.

반응형