귀퉁이 서재

OpenCV - 32. 객체 추적을 위한 Tracking API 본문

OpenCV

OpenCV - 32. 객체 추적을 위한 Tracking API

Baek Kyun Shin 2020. 12. 26. 20:51

이번 포스팅에서는 객체 추적을 위한 Tracking API에 대해 배워보겠습니다. 이번 포스팅 역시 '파이썬으로 만드는 OpenCV 프로젝트(이세우 저)'를 정리한 것임을 밝힙니다.

코드: github.com/BaekKyunShin/OpenCV_Project_Python/tree/master/08.match_track

Tracking API

OpenCV에서는 객체 추적을 위한 Tracking API를 제공합니다. Tracking API를 이용하면 쉽게 객체 추적을 할 수 있습니다. 알고리즘 이론을 몰라도 됩니다. 추적하고자 하는 객체만 지정해주면 API가 알아서 객체를 추적해줍니다. 편리하죠? OpenCV에서 제공하는 Tracking API생성자는 아래와 같습니다. 생성자는 알고리즘에 따라 다양합니다.

tracker = cv2.TrackerBoosting_create(): AdaBoost 알고리즘 기반
tracker = cv2.TrackerMIL_create(): MIL(Multiple Instance Learning) 알고리즘 기반
tracker = cv2.TrackerKCF_create(): KCF(Kernelized Correlation Filters) 알고리즘 기반
tracker = cv2.TrackerTLD_create(): TLD(Tracking, Learning and Detection) 알고리즘 기반
tracker = cv2.TrackerMedianFlow_create(): 객체의 전방향/역방향을 추적해서 불일치성을 측정
tracker = cv2.TrackerGOTURN_cretae(): CNN(Convolutional Neural Networks) 기반 - OpenCV 3.4 버전에서는 버그로 동작이 안 됨
tracker = cv2.TrackerCSRT_create(): CSRT(Channel and Spatial Reliability)
tracker = cv2.TrackerMOSSE_create(): 내부적으로 그레이 스케일 사용

저도 각 알고리즘이 구체적으로 어떻게 동작하는지 모릅니다. 그냥 '이런 알고리즘이 있구나'하고 넘어가도 무방합니다. 생성한 Tracker는 init() 함수로 초기화할 수 있습니다. init() 함수의 파라미터로 두 가지를 전달해야 합니다. 입력 영상과 추적 대상 객체가 있는 좌표입니다. 

  • retval = cv2.Tracker.init(img, boundingBox): Tracker 초기화
    img: 입력 영상
    boundingBox: 추적 대상 객체가 있는 좌표 (x, y)

초기화 후 새로운 영상 프레임에서 추적 대상 객체의 위치를 찾기 위해 update() 함수를 호출해야 합니다.

  • retval, boundingBox = cv2.Tracker.update(img): 새로운 프레임에서 추적 대상 객체 위치 찾기
    img: 새로운 프레임 영상
    retval: 추적 성공 여부
    boundingBox: 새로운 프레임에서의 추적 대상 객체의 새로운 위치 (x, y, w, h)

아래 코드는 Tracking API를 이용해서 객체를 추적하는 예제입니다.

# Tracker APIs (track_trackingAPI.py)

import cv2

# 트랙커 객체 생성자 함수 리스트 ---①
trackers = [cv2.TrackerBoosting_create,
            cv2.TrackerMIL_create,
            cv2.TrackerKCF_create,
            cv2.TrackerTLD_create,
            cv2.TrackerMedianFlow_create,
            cv2.TrackerGOTURN_create, #버그로 오류 발생
            cv2.TrackerCSRT_create,
            cv2.TrackerMOSSE_create]
trackerIdx = 0  # 트랙커 생성자 함수 선택 인덱스
tracker = None
isFirst = True

video_src = 0 # 비디오 파일과 카메라 선택 ---②
video_src = "../img/highway.mp4"
cap = cv2.VideoCapture(video_src)
fps = cap.get(cv2.CAP_PROP_FPS) # 프레임 수 구하기
delay = int(1000/fps)
win_name = 'Tracking APIs'
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print('Cannot read video file')
        break
    img_draw = frame.copy()
    if tracker is None: # 트랙커 생성 안된 경우
        cv2.putText(img_draw, "Press the Space to set ROI!!", \
            (100,80), cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2,cv2.LINE_AA)
    else:
        ok, bbox = tracker.update(frame)   # 새로운 프레임에서 추적 위치 찾기 ---③
        (x,y,w,h) = bbox
        if ok: # 추적 성공
            cv2.rectangle(img_draw, (int(x), int(y)), (int(x + w), int(y + h)), \
                          (0,255,0), 2, 1)
        else : # 추적 실패
            cv2.putText(img_draw, "Tracking fail.", (100,80), \
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75,(0,0,255),2,cv2.LINE_AA)
    trackerName = tracker.__class__.__name__
    cv2.putText(img_draw, str(trackerIdx) + ":"+trackerName , (100,20), \
                 cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0,255,0),2,cv2.LINE_AA)

    cv2.imshow(win_name, img_draw)
    key = cv2.waitKey(delay) & 0xff
    # 스페이스 바 또는 비디오 파일 최초 실행 ---④
    if key == ord(' ') or (video_src != 0 and isFirst): 
        isFirst = False
        roi = cv2.selectROI(win_name, frame, False)  # 초기 객체 위치 설정
        if roi[2] and roi[3]:         # 위치 설정 값 있는 경우
            tracker = trackers[trackerIdx]()    #트랙커 객체 생성 ---⑤
            isInit = tracker.init(frame, roi)
    elif key in range(48, 56): # 0~7 숫자 입력   ---⑥
        trackerIdx = key-48     # 선택한 숫자로 트랙커 인덱스 수정
        if bbox is not None:
            tracker = trackers[trackerIdx]() # 선택한 숫자의 트랙커 객체 생성 ---⑦
            isInit = tracker.init(frame, bbox) # 이전 추적 위치로 추적 위치 초기화
    elif key == 27 : 
        break
else:
    print( "Could not open video")
cap.release()
cv2.destroyAllWindows()

코드를 처음 실행하면 화면이 멈춰있을 겁니다. 먼저 추적을 원하는 객체를 드래그합니다. 다음으로 스페이스(space) 키를 누릅니다. 그러면 알아서 재생되고, 객체 추적을 시작합니다. 키보드 0~7 숫자 키를 눌러 트랙커 알고리즘을 선택할 수 있습니다. 다만 5를 누르면 오류가 뜨면서 종료가 될 겁니다. OpenCV 3.4 버전에서 cv2.TrackerGOTURN_create() 알고리즘에 버그가 있기 때문입니다. 5를 제외하고 0부터 7까지 숫자를 눌러봅시다. 화면 상단의 0:TrackerBoosting, 1:TrackerMIL 등이 뜰 겁니다. 현재 어떤 트랙커로 객체 추적을 하고 있는지를 나타내는 표시입니다.

Comments