Skip to content

Commit

Permalink
add dtb70 and tcolor128 interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
huanglianghua committed Dec 4, 2018
1 parent bd854b6 commit 2b09e33
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 5 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# GOT-10k Python Toolkit

This repository contains the official python toolkit for running experiments and evaluate performance on [GOT-10k](https://got-10k.github.io) benchmark. For convenience, it also provides unofficial implementation of tracking pipelines for [OTB](http://cvlab.hanyang.ac.kr/tracker_benchmark/index.html) and [VOT](http://votchallenge.net) benchmarks. The code is written in pure python and is compile-free. Although we support both python2 and python3, we recommend python3 for better performance.
This repository contains the official python toolkit for running experiments and evaluate performance on [GOT-10k](https://got-10k.github.io) benchmark. The code is written in pure python and is compile-free. Although we support both python2 and python3, we recommend python3 for better performance.

For convenience, the toolkit also provides unofficial implementation of dataset interfaces and tracking pipelines for [OTB](http://cvlab.hanyang.ac.kr/tracker_benchmark/index.html), [VOT](http://votchallenge.net), [DTB70](https://github.com/flyers/drone-tracking) and [TColor128](http://www.dabi.temple.edu/~hbling/data/TColor-128/TColor-128.html) benchmarks.

[GOT-10k](https://got-10k.github.io) is a large, high-diversity and one-shot database for evaluating generic purposed visual trackers. If you use the GOT-10k database or toolkits for a research publication, please consider citing:

Expand Down
2 changes: 2 additions & 0 deletions got10k/datasets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@
from .got10k import GOT10k
from .otb import OTB
from .vot import VOT
from .dtb70 import DTB70
from .tcolor128 import TColor128
from .vid import ImageNetVID
68 changes: 68 additions & 0 deletions got10k/datasets/dtb70.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from __future__ import absolute_import, print_function

import os
import glob
import numpy as np
import six


class DTB70(object):
"""`DTB70 <https://github.com/flyers/drone-tracking>`_ Dataset.
Publication:
``Visual object tracking for unmanned aerial vehicles: A benchmark and new motion models``,
Y. Wu, J. Lim and M.-H. Yang, IEEE TPAMI 2015.
Args:
root_dir (string): Root directory of dataset where sequence
folders exist.
"""
def __init__(self, root_dir):
super(DTB70, self).__init__()
self.root_dir = root_dir
self._check_integrity(root_dir)

self.anno_files = sorted(glob.glob(
os.path.join(root_dir, '*/groundtruth_rect.txt')))
self.seq_dirs = [os.path.dirname(f) for f in self.anno_files]
self.seq_names = [os.path.basename(d) for d in self.seq_dirs]

def __getitem__(self, index):
r"""
Args:
index (integer or string): Index or name of a sequence.
Returns:
tuple: (img_files, anno), where ``img_files`` is a list of
file names and ``anno`` is a N x 4 (rectangles) numpy array.
"""
if isinstance(index, six.string_types):
if not index in self.seq_names:
raise Exception('Sequence {} not found.'.format(index))
index = self.seq_names.index(index)

img_files = sorted(glob.glob(
os.path.join(self.seq_dirs[index], 'img/*.jpg')))
anno = np.loadtxt(self.anno_files[index], delimiter=',')
assert len(img_files) == len(anno)
assert anno.shape[1] == 4

return img_files, anno

def __len__(self):
return len(self.seq_names)

def _check_integrity(self, root_dir):
seq_names = os.listdir(root_dir)
seq_names = [n for n in seq_names if not n[0] == '.']

if os.path.isdir(root_dir) and len(seq_names) > 0:
# check each sequence folder
for seq_name in seq_names:
seq_dir = os.path.join(root_dir, seq_name)
if not os.path.isdir(seq_dir):
print('Warning: sequence %s not exist.' % seq_name)
else:
# dataset not exist
raise Exception('Dataset not found or corrupted. ' +
'You can use download=True to download it.')
98 changes: 98 additions & 0 deletions got10k/datasets/tcolor128.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
from __future__ import absolute_import, print_function

import os
import glob
import numpy as np
import six

from ..utils.ioutils import download, extract


class TColor128(object):
"""`TColor128 <http://www.dabi.temple.edu/~hbling/data/TColor-128/TColor-128.html>`_ Dataset.
Publication:
``Encoding color information for visual tracking: algorithms and benchmark``,
P. Liang, E. Blasch and H. Ling, TIP, 2015.
Args:
root_dir (string): Root directory of dataset where sequence
folders exist.
"""
def __init__(self, root_dir, download=True):
super(TColor128, self).__init__()
self.root_dir = root_dir
if download:
self._download(root_dir)
self._check_integrity(root_dir)

self.anno_files = sorted(glob.glob(
os.path.join(root_dir, '*/*_gt.txt')))
self.seq_dirs = [os.path.dirname(f) for f in self.anno_files]
self.seq_names = [os.path.basename(d) for d in self.seq_dirs]
# valid frame range for each sequence
self.range_files = [os.path.join(
root_dir, '%s/%s_frames.txt' % (n, n))
for n in self.seq_names]

def __getitem__(self, index):
r"""
Args:
index (integer or string): Index or name of a sequence.
Returns:
tuple: (img_files, anno), where ``img_files`` is a list of
file names and ``anno`` is a N x 4 (rectangles) numpy array.
"""
if isinstance(index, six.string_types):
if not index in self.seq_names:
raise Exception('Sequence {} not found.'.format(index))
index = self.seq_names.index(index)

# load valid frame range
frames = np.loadtxt(
self.range_files[index], dtype=int, delimiter=',')
img_files = [os.path.join(
self.seq_dirs[index], 'img/%04d.jpg' % f)
for f in range(frames[0], frames[1] + 1)]

# load annotations
anno = np.loadtxt(self.anno_files[index], delimiter=',')
assert len(img_files) == len(anno)
assert anno.shape[1] == 4

return img_files, anno

def __len__(self):
return len(self.seq_names)

def _download(self, root_dir):
if not os.path.isdir(root_dir):
os.makedirs(root_dir)
elif len(os.listdir(root_dir)) > 100:
print('Files already downloaded.')
return

url = 'http://www.dabi.temple.edu/~hbling/data/TColor-128/Temple-color-128.zip'
zip_file = os.path.join(root_dir, 'Temple-color-128.zip')
print('Downloading to %s...' % zip_file)
download(url, zip_file)
print('\nExtracting to %s...' % root_dir)
extract(zip_file, root_dir)

return root_dir

def _check_integrity(self, root_dir):
seq_names = os.listdir(root_dir)
seq_names = [n for n in seq_names if not n[0] == '.']

if os.path.isdir(root_dir) and len(seq_names) > 0:
# check each sequence folder
for seq_name in seq_names:
seq_dir = os.path.join(root_dir, seq_name)
if not os.path.isdir(seq_dir):
print('Warning: sequence %s not exist.' % seq_name)
else:
# dataset not exist
raise Exception('Dataset not found or corrupted. ' +
'You can use download=True to download it.')
2 changes: 2 additions & 0 deletions got10k/experiments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@
from .got10k import ExperimentGOT10k
from .otb import ExperimentOTB
from .vot import ExperimentVOT
from .dtb70 import ExperimentDTB70
from .tcolor128 import ExperimentTColor128
27 changes: 27 additions & 0 deletions got10k/experiments/dtb70.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from __future__ import absolute_import

import os

from .otb import ExperimentOTB
from ..datasets import DTB70


class ExperimentDTB70(ExperimentOTB):
r"""Experiment pipeline and evaluation toolkit for DTB70 dataset.
Args:
root_dir (string): Root directory of DTB70 dataset.
result_dir (string, optional): Directory for storing tracking
results. Default is ``./results``.
report_dir (string, optional): Directory for storing performance
evaluation results. Default is ``./reports``.
"""
def __init__(self, root_dir,
result_dir='results', report_dir='reports'):
self.dataset = DTB70(root_dir)
self.result_dir = os.path.join(result_dir, 'DTB70')
self.report_dir = os.path.join(report_dir, 'DTB70')
# as nbins_iou increases, the success score
# converges to the average overlap (AO)
self.nbins_iou = 21
self.nbins_ce = 51
3 changes: 2 additions & 1 deletion got10k/experiments/otb.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ def __init__(self, root_dir, version=2015,
self.nbins_ce = 51

def run(self, tracker, visualize=False):
print('Running tracker %s on OTB...' % tracker.name)
print('Running tracker %s on %s...' % (
tracker.name, type(self.dataset).__name__))

# loop over the complete dataset
for s, (img_files, anno) in enumerate(self.dataset):
Expand Down
27 changes: 27 additions & 0 deletions got10k/experiments/tcolor128.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from __future__ import absolute_import

import os

from .otb import ExperimentOTB
from ..datasets import TColor128


class ExperimentTColor128(ExperimentOTB):
r"""Experiment pipeline and evaluation toolkit for TColor128 dataset.
Args:
root_dir (string): Root directory of TColor128 dataset.
result_dir (string, optional): Directory for storing tracking
results. Default is ``./results``.
report_dir (string, optional): Directory for storing performance
evaluation results. Default is ``./reports``.
"""
def __init__(self, root_dir,
result_dir='results', report_dir='reports'):
self.dataset = TColor128(root_dir)
self.result_dir = os.path.join(result_dir, 'TColor128')
self.report_dir = os.path.join(report_dir, 'TColor128')
# as nbins_iou increases, the success score
# converges to the average overlap (AO)
self.nbins_iou = 21
self.nbins_ce = 51
3 changes: 2 additions & 1 deletion got10k/experiments/vot.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ def __init__(self, root_dir, version=2017,
'size_change', 'motion_change', 'empty']

def run(self, tracker, visualize=False):
print('Running tracker %s on VOT...' % tracker.name)
print('Running tracker %s on %s...' % (
tracker.name, type(self.dataset).__name__))

# run all specified experiments
if 'supervised' in self.experiments:
Expand Down
12 changes: 11 additions & 1 deletion tests/test_datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import os
import random

from got10k.datasets import GOT10k, OTB, VOT, ImageNetVID
from got10k.datasets import GOT10k, OTB, VOT, DTB70, TColor128, ImageNetVID


class TestDatasets(unittest.TestCase):
Expand Down Expand Up @@ -38,6 +38,16 @@ def test_vot(self):
dataset = VOT(root_dir, anno_type='rect', return_meta=True)
self._check_dataset(dataset)

def test_dtb70(self):
root_dir = os.path.join(self.data_dir, 'DTB70')
dataset = DTB70(root_dir)
self._check_dataset(dataset)

def test_tcolor128(self):
root_dir = os.path.join(self.data_dir, 'Temple-color-128')
dataset = TColor128(root_dir)
self._check_dataset(dataset)

def test_vid(self):
root_dir = os.path.join(self.data_dir, 'ILSVRC')
dataset = ImageNetVID(root_dir, subset=('train', 'val'))
Expand Down
18 changes: 17 additions & 1 deletion tests/test_experiments.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from got10k.trackers import IdentityTracker
from got10k.experiments import ExperimentGOT10k, ExperimentOTB, \
ExperimentVOT
ExperimentVOT, ExperimentDTB70, ExperimentTColor128


class TestExperiments(unittest.TestCase):
Expand Down Expand Up @@ -41,6 +41,22 @@ def test_vot(self):
# report performance
experiment.report([self.tracker.name])

def test_dtb70(self):
root_dir = os.path.join(self.data_dir, 'DTB70')
# run experiment
experiment = ExperimentDTB70(root_dir)
experiment.run(self.tracker, visualize=False)
# report performance
experiment.report([self.tracker.name])

def test_tcolor128(self):
root_dir = os.path.join(self.data_dir, 'Temple-color-128')
# run experiment
experiment = ExperimentTColor128(root_dir)
experiment.run(self.tracker, visualize=False)
# report performance
experiment.report([self.tracker.name])


if __name__ == '__main__':
unittest.main()

0 comments on commit 2b09e33

Please sign in to comment.