diff --git a/sloth/annotations/container.py b/sloth/annotations/container.py index f081bad..dd39f69 100644 --- a/sloth/annotations/container.py +++ b/sloth/annotations/container.py @@ -1,5 +1,4 @@ import os -import sys import fnmatch import time import numpy as np @@ -11,21 +10,21 @@ LOG = logging.getLogger(__name__) try: import cPickle as pickle -except: +except ImportError: import pickle try: import json -except: +except ImportError: pass try: import yaml -except: +except ImportError: pass try: import okapy import okapy.videoio as okv _use_pil = False -except: +except ImportError: try: from PIL import Image _use_pil = True @@ -85,7 +84,7 @@ class AnnotationContainer: return self._filename def clear(self): - self._annotations = [] # TODO Why isn't this used? Annotations are passed as parameters instead. Let's have encapsulation. + self._annotations = [] # TODO Why isn't this used? Annotations are passed as parameters instead. Let's have encapsulation. self._filename = None self._video_cache = {} @@ -375,8 +374,8 @@ class FileNameListContainer(AnnotationContainer): for line in f: line = line.strip() fileitem = { - 'filename': line, - 'class': 'image', + 'filename': line, + 'class': 'image', 'annotations': [], } annotations.append(fileitem) @@ -384,8 +383,7 @@ class FileNameListContainer(AnnotationContainer): return annotations def serializeToFile(self, filename, annotations): - raise NotImplemented( - "FileNameListContainer.save() is not implemented yet.") + raise NotImplemented("FileNameListContainer.save() is not implemented yet.") class FeretContainer(AnnotationContainer): @@ -405,15 +403,12 @@ class FeretContainer(AnnotationContainer): fileitem = { 'filename': s[0] + ".bmp", 'class': 'image', + 'annotations': [ + {'class': 'left_eye', 'x': int(s[1]), 'y': int(s[2])}, + {'class': 'right_eye', 'x': int(s[3]), 'y': int(s[4])}, + {'class': 'mouth', 'x': int(s[5]), 'y': int(s[6])} + ] } - fileitem['annotations'] = [ - {'class': 'left_eye', - 'x': int(s[1]), 'y': int(s[2])}, - {'class': 'right_eye', - 'x': int(s[3]), 'y': int(s[4])}, - {'class': 'mouth', - 'x': int(s[5]), 'y': int(s[6])} - ] annotations.append(fileitem) return annotations diff --git a/sloth/conf/default_config.py b/sloth/conf/default_config.py index 547f6c1..52d939f 100644 --- a/sloth/conf/default_config.py +++ b/sloth/conf/default_config.py @@ -37,7 +37,7 @@ LABELS = ( { 'attributes': { 'class': 'Face', - }, + }, 'inserter': 'sloth.items.RectItemInserter', 'item': 'sloth.items.RectItem', 'hotkey': 'f', @@ -46,7 +46,7 @@ LABELS = ( { 'attributes': { 'class': 'rect', - }, + }, 'inserter': 'sloth.items.RectItemInserter', 'item': 'sloth.items.RectItem', 'hotkey': 'r', diff --git a/sloth/plugins/__init__.py b/sloth/plugins/__init__.py index 4625f30..6c33bff 100644 --- a/sloth/plugins/__init__.py +++ b/sloth/plugins/__init__.py @@ -1,8 +1,11 @@ from PyQt4.QtGui import * from PyQt4.QtCore import * import logging + + LOG = logging.getLogger(__name__) + class CopyAnnotationsPlugin(QObject): def __init__(self, labeltool, class_filter=None, frame_range=1, overlap_threshold=None, prefix=''): QObject.__init__(self) @@ -14,7 +17,7 @@ class CopyAnnotationsPlugin(QObject): self._labeltool = labeltool self._wnd = labeltool.mainWindow() - self._sc = QAction("Copy labels from previous image/frame", self._wnd) + self._sc = QAction("Copy labels from previous image/frame", self._wnd) self._sc.triggered.connect(self.copy) def copy(self): @@ -53,11 +56,8 @@ class CopyAnnotationsPlugin(QObject): for annotation in image_item.getAnnotations()['annotations']: # check class filter if self._class_filter is not None: - if 'class' not in annotation: - continue # do not copy - if annotation['class'] not in self._class_filter: - log - continue # do not copy + if annotation.get('class', None) not in self._class_filter: + continue # do not copy annotations.append(annotation) return annotations diff --git a/sloth/utils/__init__.py b/sloth/utils/__init__.py index 785b85a..09e5d33 100644 --- a/sloth/utils/__init__.py +++ b/sloth/utils/__init__.py @@ -1,8 +1,9 @@ -from sloth.core.exceptions import NotImplementedException -from PyQt4.QtGui import QImage, qRgb import numpy as np import random import colorsys +from PyQt4.QtGui import QImage, qRgb +from sloth.core.exceptions import NotImplementedException + gray_color_table = [qRgb(i, i, i) for i in range(256)] @@ -60,5 +61,4 @@ def gen_colors(s=0.99, v=0.99, h=None, color_space='rgb', _golden_ratio_conjugat while True: h += _golden_ratio_conjugate h %= 1 - yield cs_convert(h, s, v) - + yield cs_convert(h, s, v) \ No newline at end of file diff --git a/sloth/utils/bind.py b/sloth/utils/bind.py index 1d208ee..0852650 100644 --- a/sloth/utils/bind.py +++ b/sloth/utils/bind.py @@ -1,12 +1,14 @@ def bind(fun, *args): return lambda: fun(*args) + def compose_noargs(funs): def tmp(): for f in funs: f() return tmp + def compose(funs): def tmp(*args, **kwargs): for f in funs: diff --git a/tests/container_test.py b/tests/container_test.py index 819668d..10bdac7 100644 --- a/tests/container_test.py +++ b/tests/container_test.py @@ -6,17 +6,8 @@ class MockupContainer: def someFileAnnotations(i): - annotations = [] - annotations.append({'type': 'rect', - 'x': 10 * i, - 'y': '20', - 'w': '40', - 'h': '60'}) - annotations.append({'type': 'rect', - 'x': '80', - 'y': 20 * i, - 'w': '40', - 'h': '60'}) + annotations = [{'type': 'rect', 'x': 10 * i, 'y': '20', 'w': '40', 'h': '60'}, + {'type': 'rect', 'x': '80', 'y': 20 * i, 'w': '40', 'h': '60'}] for k in range(i): annotations.append({'type': 'point', 'x': 30 * k, @@ -27,12 +18,12 @@ def someFileAnnotations(i): def someAnnotations(): annotations = [] for i in range(5): - file = { + ann = { 'filename': 'file%d.png' % i, 'type': 'image', 'annotations': someFileAnnotations(i) } - annotations.append(file) + annotations.append(ann) return annotations diff --git a/tests/item_factory_test.py b/tests/item_factory_test.py index 5703bb2..5e4eba8 100644 --- a/tests/item_factory_test.py +++ b/tests/item_factory_test.py @@ -1,9 +1,18 @@ import pytest from sloth.items import Factory -class MockupRectItem: pass -class MockupPointItem: pass -class MockupPolygonItem: pass + +class MockupRectItem: + pass + + +class MockupPointItem: + pass + + +class MockupPolygonItem: + pass + def _create_factory(): itemfactory = Factory({'point': MockupPointItem, @@ -12,6 +21,7 @@ def _create_factory(): return itemfactory + def test_register(): itemfactory = _create_factory() @@ -24,11 +34,13 @@ def test_register(): item = itemfactory.create('polygon2') assert item is None + def test_register_fail(): itemfactory = _create_factory() with pytest.raises(Exception): itemfactory.register('rect', MockupRectItem) + def test_register_replace(): itemfactory = _create_factory() @@ -36,6 +48,7 @@ def test_register_replace(): item = itemfactory.create('rect') assert isinstance(item, MockupPolygonItem) + def test_clear(): itemfactory = _create_factory() @@ -51,5 +64,4 @@ def test_clear(): assert isinstance(item, MockupPolygonItem) itemfactory.clear() assert itemfactory.create('point') is None - assert itemfactory.create('polygon') is None - + assert itemfactory.create('polygon') is None \ No newline at end of file