Skip to content

Commit

Permalink
Documentation, some refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
lukacu committed Apr 19, 2021
1 parent 54432f8 commit 5daca18
Show file tree
Hide file tree
Showing 17 changed files with 754 additions and 461 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
The VOT evaluation toolkit
==========================

This repository contains the official evaluation toolkit for the [Visual Object Tracking (VOT) challenge](http://votchallenge.net/). This is the new version of the toolkit, implemented in Python 3 language, if you are looking for the old Matlab version, you can find it [here](https://github.com/vicoslab/toolkit).
This repository contains the official evaluation toolkit for the [Visual Object Tracking (VOT) challenge](http://votchallenge.net/). This is the official version of the toolkit, implemented in Python 3 language. If you are looking for the old Matlab version, you can find an archived repository [here](https://github.com/vicoslab/toolkit-legacy).

For more detailed informations consult the documentation available in the source or a compiled version of the documentation [here](http://www.votchallenge.net/howto/). You can also subscribe to the VOT [mailing list](https://service.ait.ac.at/mailman/listinfo/votchallenge) to receive news about challenges and important software updates or join our [support form](https://groups.google.com/forum/?hl=en#!forum/votchallenge-help) to ask questions.

Expand Down
43 changes: 35 additions & 8 deletions vot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,49 @@

from .version import __version__

class VOTException(Exception):
_logger = logging.getLogger("vot")

def get_logger() -> logging.Logger:
"""Returns the default logger object used to log different messages.
Returns:
logging.Logger: Logger handle
"""
return _logger

class ToolkitException(Exception):
"""Base class for all toolkit related exceptions
"""
pass

def toolkit_version():

def toolkit_version() -> str:
"""Returns toolkit version as a string
Returns:
str: Version of the toolkit
"""
return __version__

def check_updates():
def check_updates() -> bool:
"""Checks for toolkit updates on Github, requires internet access, fails silently on errors.
Returns:
bool: True if an update is available, False otherwise.
"""

import re
import packaging.version as packaging
import requests
pattern = r"^__version__ = ['\"]([^'\"]*)['\"]"

version_url = "https://github.com/votchallenge/vot-toolkit-python/raw/master/vot/version.py"

logger = logging.getLogger("vot")

try:
logger.debug("Checking for new version")
get_logger().debug("Checking for new version")
response = requests.get(version_url, timeout=2)
except Exception as e:
logger.debug("Unable to retrieve version information %s", e)
get_logger().debug("Unable to retrieve version information %s", e)
return False, None

if not response:
Expand All @@ -40,7 +62,12 @@ def check_updates():
else:
return False, None

def check_debug():
def check_debug() -> bool:
"""Checks if debug is enabled for the toolkit via an environment variable.
Returns:
bool: True if debug is enabled, False otherwise
"""
var = os.environ.get("VOT_TOOLKIT_DEBUG", "false").lower()
return var in ["true", "1"]

3 changes: 3 additions & 0 deletions vot/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@


# Just a shortcut for the CLI interface so that it can be run as a "vot" module.

from vot.utilities.cli import main

if __name__ == '__main__':
Expand Down
4 changes: 2 additions & 2 deletions vot/analysis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from attributee import Attributee, String

from vot import VOTException
from vot import ToolkitException
from vot.tracker import Tracker
from vot.dataset import Sequence
from vot.experiment import Experiment
Expand All @@ -23,7 +23,7 @@

analysis_registry = ClassRegistry("vot_analysis")

class MissingResultsException(VOTException):
class MissingResultsException(ToolkitException):
"""Exception class that denotes missing results during analysis
"""
pass
Expand Down
4 changes: 2 additions & 2 deletions vot/analysis/_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from cachetools import Cache
from bidict import bidict

from vot import VOTException
from vot import ToolkitException
from vot.dataset import Sequence
from vot.tracker import Tracker
from vot.experiment import Experiment
Expand Down Expand Up @@ -42,7 +42,7 @@ def unwrap(arg):
else:
return arg

class AnalysisError(VOTException):
class AnalysisError(ToolkitException):
def __init__(self, cause, task=None):
self._tasks = []
self._cause = cause
Expand Down
4 changes: 2 additions & 2 deletions vot/dataset/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
from PIL.Image import Image
import numpy as np

from vot import VOTException
from vot import ToolkitException
from vot.utilities import read_properties
from vot.region import parse

import cv2

class DatasetException(VOTException):
class DatasetException(ToolkitException):
pass

class Channel(ABC):
Expand Down
5 changes: 1 addition & 4 deletions vot/experiment/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@


import os
import json
import glob
import logging
import typing
from datetime import datetime
from abc import abstractmethod, ABC
from abc import abstractmethod

from class_registry import ClassRegistry

Expand Down
2 changes: 1 addition & 1 deletion vot/region/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from typing import Tuple
from enum import Enum

from vot import VOTException
from vot import ToolkitException
from vot.utilities.draw import DrawHandle

class RegionException(Exception):
Expand Down
4 changes: 2 additions & 2 deletions vot/stack/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
import unittest
import yaml

from vot.workspace import Workspace, VoidStorage
from vot.workspace import Workspace, NullStorage
from vot.stack import Stack, list_integrated_stacks, resolve_stack

class NoWorkspace:

@property
def storage(self):
return VoidStorage()
return NullStorage()

class TestStacks(unittest.TestCase):

Expand Down
6 changes: 3 additions & 3 deletions vot/tracker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@

import yaml

from vot import VOTException
from vot import ToolkitException
from vot.dataset import Frame
from vot.region import Region
from vot.utilities import to_string

logger = logging.getLogger("vot")

class TrackerException(VOTException):
class TrackerException(ToolkitException):
def __init__(self, *args, tracker, tracker_log=None):
super().__init__(*args)
self._tracker_log = tracker_log
Expand Down Expand Up @@ -138,7 +138,7 @@ def resolve(self, *references, storage=None, skip_unknown=True, resolve_plural=T

if not identifier in self._trackers:
if not skip_unknown:
raise VOTException("Unable to resolve tracker reference: {}".format(reference))
raise ToolkitException("Unable to resolve tracker reference: {}".format(reference))
else:
continue

Expand Down
45 changes: 30 additions & 15 deletions vot/utilities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

from numbers import Number
from typing import Tuple
import typing
from vot import get_logger

import six
import colorama
Expand Down Expand Up @@ -68,6 +70,7 @@ def flip(size: Tuple[Number, Number]) -> Tuple[Number, Number]:
from tqdm import tqdm

class Progress(object):

class StreamProxy(object):

def write(self, x):
Expand All @@ -83,38 +86,47 @@ def logstream():
return Progress.StreamProxy()

def __init__(self, description="Processing", total=100):
self._tqdm = tqdm(disable=False if is_notebook() else None,
bar_format=" {desc:20.20} |{bar}| {percentage:3.0f}% [{elapsed}<{remaining}]")
self._tqdm.desc = description
self._tqdm.total = total
if self._tqdm.disable:
silent = get_logger().level > logging.INFO

if not silent:
self._tqdm = tqdm(disable=False if is_notebook() else None,
bar_format=" {desc:20.20} |{bar}| {percentage:3.0f}% [{elapsed}<{remaining}]")
self._tqdm.desc = description
self._tqdm.total = total
if silent or self._tqdm.disable:
self._tqdm = None
self._value = 0
self._total = total
self._total = total if not silent else 0

def _percent(self, n):
return int((n * 100) / self._total)

def absolute(self, value):
if self._tqdm is None:
if self._total == 0:
return
prev = self._value
self._value = max(0, min(value, self._total))
if self._percent(prev) != self._percent(self._value):
print("%d %%" % self._percent(self._value), end=' ')
print("%d %%" % self._percent(self._value))
else:
self._tqdm.update(value - self._tqdm.n) # will also set self.n = b * bsize

def relative(self, n):
if self._tqdm is None:
if self._total == 0:
return
prev = self._value
self._value = max(0, min(self._value + n, self._total))
if self._percent(prev) != self._percent(self._value):
print("%d %%" % self._percent(self._value), end=' ')
print("%d %%" % self._percent(self._value))
else:
self._tqdm.update(n) # will also set self.n = b * bsize

def total(self, t):
if self._tqdm is None:
if self._total == 0:
return
self._total = t
else:
if self._tqdm.total == t:
Expand All @@ -131,8 +143,6 @@ def __exit__(self, exc_type, exc_value, traceback):
def close(self):
if self._tqdm:
self._tqdm.close()
else:
print("")

def extract_files(archive, destination, callback = None):
from zipfile import ZipFile
Expand All @@ -148,11 +158,16 @@ def extract_files(archive, destination, callback = None):
if callback:
callback(1, total)

def read_properties(filename, delimiter='='):
''' Reads a given properties file with each line of the format key=value.
Returns a dictionary containing the pairs.
filename -- the name of the file to be read
'''
def read_properties(filename: str, delimiter: str = '=') -> typing.Dict[str, str]:
"""Reads a given properties file with each line of the format key=value. Returns a dictionary containing the pairs.
Args:
filename (str): The name of the file to be read.
delimiter (str, optional): Key-value delimiter. Defaults to '='.
Returns:
[typing.Dict[str, str]]: Resuting properties as a dictionary
"""
if not os.path.exists(filename):
return {}
open_kwargs = {'mode': 'r', 'newline': ''} if six.PY3 else {'mode': 'rb'}
Expand Down
Loading

0 comments on commit 5daca18

Please sign in to comment.