티스토리 뷰
Detection 기반의 Tracking 방법 중 대표적인 방법인 SORT의 코드와 논문을 보다보면 Kalman Filter를 사용하여 트래킹하는 객체의 위치를 추정함을 알 수 있다. 그런데, 이 Kalman Filter가 그냥 가져다 쓰는 건 쉬울 수 있어도 이해하기란 참 어려웠다. 관련 포스트를 몇개 읽어보고 "칼만 필터는 어렵지 않아" 라는 책도 읽어보았지만, 대강의 큰 그림은 이해가 될랑~말랑 하지만 디테일하게는 이해하지 못했다...
개발을 하며 잘 구현된 알고리즘을 가져다 쓰는 걸 좋아하는 입장이지만, 제대로 이해하지 못하고 가져다 쓰기에는 너무 찜찜하다. 과연 이 복잡한 Kalman Filter가 Tracking 알고리즘의 얼마나 큰 영향을 미칠까?? 이를 제거하였을때 저하되는 성능이 극히 미미한 정도라면 굳이 이 어려운 알고리즘을 이해할 필요가 있을까?? 란 생각이 들었다. 반대로 Kalman Filter에 의한 성능 향상이 크다면, 이를 이해해야만 내가 한 단계 더 성장할 수 있을거란 생각도 들었다.
먼저, 이에 대한 실험을 진행하기 위하여 아래의 두 프로젝트를 이용하였다. 첫번째 프로젝트는 SORT의 Official Implementation이고, 두번째 프로젝트는 Tracking 알고리즘의 성능 평가 방법을 구현한 프로젝트이다.
https://github.com/abewley/sort
https://github.com/JonathonLuiten/TrackEval
SORT 논문의 Table 1을 보면, Detector로 FrRCNN(VGG16)이라는 모델을 사용했을때, MOT15 데이터셋의 특정 씬들에 대상으로 ID Switching 은 274회, MOTA는 34.0이라는 수치를 달성한 것을 확인할 수 있다.
그리고, abewley/sort 프로젝트에서 위 테이블의 결과가 README 파일에 존재하는 것을 확인할 수 있다.
칼만 필터를 제외했을때의 성능을 측정해보기 전에, SORT의 성능이 논문과 같이(README에 기록된 대로) 나오는지 확인을 해보았다. 그 방법은 다음과 같다.
먼저 SORT 프로젝트를 클론하고 해당 프로젝트 폴더로 이동하여 Requirements를 모두 설치한뒤 다음의 명령어를 입력하면 프로젝트 폴더내에 "output"이라는 폴더가 생긴다.
python sort.py
"output" 폴더 내부에는 MOT15 데이터셋의 특정 시퀀스들에 대한 Tracking 결과가 기록된 파일들이 저장된다.
그리고 TrackEval 프로젝트를 클론한다. 그다음으로, https://omnomnom.vision.rwth-aachen.de/data/TrackEval/data.zip 를 다운로드 받고 TrackEval 프로젝트내에 압축을 해제한다.
{TrackEval 프로젝트 루트 폴더}/data/gt/mot_challenge/seqmaps/MOT15-train.txt 의 내용을 아래와 같이 수정한다. 알고리즘의 성능 평가용 영상을 논문에서 사용된대로 맞춰주기 위함이다.
name
TUD-Campus
ETH-Sunnyday
ETH-Pedcross2
ADL-Rundle-8
KITTI-17
Venice-2
그리고, {TrackEval 프로젝트 루트 폴더}/data/trackers/mot_challenge/MOT15-train/ 폴더로 이동하고 다음의 명령어를 입력한다.
mkdir SORT
mkdir SORT/data
이후 python sort.py 에 의해 생성된 output 폴더에 있는 txt 파일들을 {TrackEval 프로젝트 루트 폴더}/data/trackers/mot_challenge/MOT15-train/SORT/data/ 내에 이동시킨다.
다음의 명령어를 입력하면 성능 평가 과정이 진행되고 결과가 출력된다.
python TrackEval/scripts/run_mot_challenge.py --BENCHMARK MOT15 --TRACKERS_TO_EVAL SORT
MOTA는 33.967, ID Switching(IDSW) 횟수는 274회가 나온다. MOTA는 소수점 둘째 자리에서 반올림하면 34.0이 나온다. 논문과 프로젝트 페이지에 기록된대로 동일한 값들이 나옴을 확인할 수 있다!
이제 칼만 필터를 생략했을때 성능을 측정해보자.
먼저 abeley/sort 프로젝트에서 sort.py 에 아래 클래스를 추가하자.
class BoxTracker(object):
"""
This class represents the internal state of individual tracked objects observed as bbox.
"""
count = 0
def __init__(self,bbox):
"""
Initialises a tracker using initial bounding box.
"""
#define constant velocity model
self.bbox = bbox[:4]
self.time_since_update = 0
self.id = BoxTracker.count
BoxTracker.count += 1
self.history = []
self.hits = 0
self.hit_streak = 0
self.age = 0
def update(self,bbox):
"""
Updates the state vector with observed bbox.
"""
self.time_since_update = 0
self.history = []
self.hits += 1
self.hit_streak += 1
self.bbox = bbox[:4]
def predict(self):
"""
Advances the state vector and returns the predicted bounding box estimate.
"""
self.age += 1
if(self.time_since_update>0):
self.hit_streak = 0
self.time_since_update += 1
return [self.bbox]
def get_state(self):
"""
Returns the current bounding box estimate.
"""
return [self.bbox]
그리고, Sort 클래스의 update 함수내에서 아래의 부분을
for i in unmatched_dets:
trk = KalmanBoxTracker(dets[i,:])
self.trackers.append(trk)
다음과 같이 수정해주자.
for i in unmatched_dets:
trk = BoxTracker(dets[i,:])
self.trackers.append(trk)
이후 아래의 명령어를 입력한다.
python sort.py
위 명령어가 정상적으로 실행됐다면 {abewley/sort 프로젝트 폴더}/output 에 txt 파일이 새로 생성될 것이다.
그리고, {TrackEval 프로젝트 루트 폴더}/data/tracker/mot_challenge/MOT15-train/ 폴더로 이동하고 다음의 명령어를 입력한다.
mkdir SORT-Not-Kalman
mkdir SORT-Not-Kalman/data
이후 python sort.py 에 의해 생성된 output 폴더에 있는 txt 파일들을 {TrackEval 프로젝트 루트 폴더}/data/tracker/mot_challenge/MOT15-train/SORT-Not-Kalman/data/ 내에 이동시킨다.
다음의 명령어를 입력하면 성능 평가 과정이 진행되고 결과가 출력된다.
python TrackEval/scripts/run_mot_challenge.py --BENCHMARK MOT15 --TRACKERS_TO_EVAL SORT-Not-Kalman
Kalman Filter를 제거하자 MOTA는 31.71, ID Switching 횟수는 344회를 기록하였다.
다음의 표는 Kalman Filter가 포함된 순정 SORT 알고리즘의 성능과 Kalman Filter를 제외했을때의 SORT 알고리즘의 성능을 비교한 것이다.
Method | MOTA | ID Sw |
SORT | 34.0 | 274 |
SORT w/o Kalman Filter | 31.7 | 344 |
MOTA는 높을수록 좋으며, ID Switching(=ID Sw)는 낮을수록 좋다. 실험 결과로 SORT에서 Kalman Filter를 제외 했을때 MOTA는 감소했으며, ID Switching은 증가하였다. 실험을 통해 Kalman Filter는 MOT15 데이터셋의 특정 영상들에 대해 효과적으로 동작하는 방법임을 검증하였다. 젠장 Kalman Filter 다시 공부하러 가야겠다...
추가로 Kalman Filter가 포함된 순정 SORT 알고리즘과 Kalman Filter를 제외했을때의 수행 시간은 다음과 같이 기록되었다. 여기서, 수행 시간은 abewley/sort 의 sort.py 를 실행하면 출력되는 속도를 의미한다. 트래킹된 총 프레임 수는 5,500이다. 해당 실험에 사용된 PC의 스펙은 CPU i5 10400, RAM 32GB 다.
Method | Execution Time (Sec) |
SORT | 7.30 |
SORT w/o Kalman Filter | 2.56 |
Kalman Filter를 제외했을때 실행속도가 약 2.8 배 고속화된 것(Execution Time(SORT)/Execution Time(SORT w/o Kalman Filter))을 확인할 수 있다. 그런데 파이썬 코드라... 실제로 C/C++ 로 포팅해보면 이정도로 차이가 날까? 란 의문이 들기는 한다.
칼만필터를 제외하고 구현한 SORT 알고리즘을 깃헙에 업로드해놓았다.
https://github.com/developer0hye/qsort
하지만 칼만필터가 모든 경우에 이상적인 건 아닙니다.
BYTETrack 논문을 읽어보면, autonomous driving scenes에서는 kalman filter를 적용했을때 성능이 저하되는 문제가 있어서 적용하지 않았다고 합니다.
슈뢰딩거의 고양이처럼 칼만 필터 또한 다루는 데이터에 대해 실제로 적용해봐야 성능을 알 수 있습니다.
'Deep Learning' 카테고리의 다른 글
[딥 러닝, Object Detection] IoU-aware Single-stage Object Detector for Accurate Localization 논문 리뷰 (0) | 2022.02.03 |
---|---|
[딥 러닝, Object Detection] Gaussian YOLOv3 논문 리뷰 (0) | 2022.01.31 |
[논문] ByteTrack 리뷰 (8) | 2021.12.23 |
[MLOPS] Shadow mode deployment (0) | 2021.11.22 |
[MLOPS] 머신러닝 프로젝트 사이클 (0) | 2021.11.22 |
- Total
- Today
- Yesterday
- cosine
- PyCharm
- 순열
- 자료구조
- 단축키
- 백준 11437
- 이분탐색
- LCA
- 파이참
- 인공지능을 위한 선형대수
- 백준
- MOT
- 조합
- ㅂ
- C++ Deploy
- 백준 11053
- 가장 긴 증가하는 부분 수열
- 문제집
- 위상 정렬 알고리즘
- 백준 1766
- 백트래킹
- FairMOT
- Lowest Common Ancestor
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |