mirror of
https://github.com/wassname/sloth.git
synced 2026-07-19 11:28:06 +08:00
implement new config system
This commit is contained in:
+7
-4
@@ -1,6 +1,6 @@
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
from sceneitems import *
|
||||
from items import *
|
||||
from annotationmodel import TypeRole, ImageRole
|
||||
import math
|
||||
import okapy
|
||||
@@ -10,7 +10,7 @@ class AnnotationScene(QGraphicsScene):
|
||||
|
||||
# TODO signal itemadded
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, items=None, inserters=None, parent=None):
|
||||
super(AnnotationScene, self).__init__(parent)
|
||||
|
||||
self.model_ = None
|
||||
@@ -20,6 +20,9 @@ class AnnotationScene(QGraphicsScene):
|
||||
self.message_ = ""
|
||||
self.last_key_ = None
|
||||
|
||||
self.itemfactory_ = Factory(items)
|
||||
self.inserterfactory_ = Factory(inserters)
|
||||
|
||||
self.setBackgroundBrush(Qt.darkGray)
|
||||
|
||||
self.setMode(None)
|
||||
@@ -93,7 +96,7 @@ class AnnotationScene(QGraphicsScene):
|
||||
for row in range(first, last+1):
|
||||
child = self.root_.child(row, 0) # get index
|
||||
_type = str(child.data(TypeRole).toPyObject()) # get type from index
|
||||
item = ItemFactory.createItem(_type, child) # create graphics item from factory
|
||||
item = self.itemfactory_.create(_type, child) # create graphics item from factory
|
||||
if item is not None:
|
||||
self.addItem(item)
|
||||
|
||||
@@ -108,7 +111,7 @@ class AnnotationScene(QGraphicsScene):
|
||||
self.inserter_ = None
|
||||
return
|
||||
|
||||
inserter = ItemFactory.createItemInserter(self.mode_['type'], self)
|
||||
inserter = self.inserterfactory_.create(self.mode_['type'], self)
|
||||
if inserter is None:
|
||||
raise InvalidArgumentException("Invalid mode")
|
||||
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
from items import ItemInserter, AnnotationGraphicsItem
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.Qt import *
|
||||
|
||||
class BodyBoundingboxItemInserter(ItemInserter):
|
||||
def __init__(self, scene, mode=None):
|
||||
ItemInserter.__init__(self, scene, mode)
|
||||
self.point_items_ = []
|
||||
self.points_ = []
|
||||
|
||||
def mousePressEvent(self, event, index):
|
||||
pos = event.scenePos()
|
||||
self.points_.append((pos.x(), pos.y()))
|
||||
item = QGraphicsEllipseItem(pos.x()-2, pos.y()-2, 4, 4)
|
||||
item.setPen(Qt.red)
|
||||
self.point_items_.append(item)
|
||||
self.scene().addItem(item)
|
||||
|
||||
event.accept()
|
||||
if self.complete(index):
|
||||
self.clear()
|
||||
|
||||
def complete(self, index):
|
||||
if len(self.points_) == 4:
|
||||
ann = {'type': 'bodybbox',
|
||||
'x1': self.points_[0][0], 'y1': self.points_[0][1],
|
||||
'x2': self.points_[1][0], 'y2': self.points_[1][1],
|
||||
'x3': self.points_[2][0], 'y3': self.points_[2][1],
|
||||
'x4': self.points_[3][0], 'y4': self.points_[3][1]}
|
||||
index.model().addAnnotation(index, ann)
|
||||
return True
|
||||
return False
|
||||
|
||||
def clear(self):
|
||||
for item in self.point_items_:
|
||||
self.scene().removeItem(item)
|
||||
self.point_items_ = []
|
||||
self.points_ = []
|
||||
|
||||
class BodyBoundingboxItem(AnnotationGraphicsItem):
|
||||
def __init__(self, index, parent=None):
|
||||
AnnotationGraphicsItem.__init__(self, index, parent)
|
||||
|
||||
self.data_ = self.index().data(DataRole).toPyObject()
|
||||
self.points_ = [(self.data_['x1'], self.data_['y1']),
|
||||
(self.data_['x2'], self.data_['y2']),
|
||||
(self.data_['x3'], self.data_['y3']),
|
||||
(self.data_['x4'], self.data_['y4'])]
|
||||
|
||||
def boundingRect(self):
|
||||
return QRectF(QPointF(0, 0), QSizeF(20, 20))
|
||||
|
||||
def paint(self, painter, option, widget = None):
|
||||
pen = self.pen()
|
||||
if self.isSelected():
|
||||
pen.setStyle(Qt.DashLine)
|
||||
painter.setPen(pen)
|
||||
painter.drawRect(self.boundingRect())
|
||||
|
||||
+13
-9
@@ -64,7 +64,7 @@ class ButtonListWidget(QWidget):
|
||||
class ButtonArea(QWidget):
|
||||
stateChanged = pyqtSignal(object)
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, labels=None, hotkeys=None, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
|
||||
self.label_names = []
|
||||
@@ -84,6 +84,14 @@ class ButtonArea(QWidget):
|
||||
self.setLayout(self.hlayout)
|
||||
self.stateChanged.connect(self.stateHasChanged)
|
||||
|
||||
if labels is not None:
|
||||
for name, prop in labels:
|
||||
self.add_label(name, prop)
|
||||
if hotkeys is not None:
|
||||
for choice, name, hotkey in hotkeys:
|
||||
self.add_hotkey(choice, name, hotkey)
|
||||
self.init_button_lists()
|
||||
|
||||
def stateHasChanged(self, state):
|
||||
print "stateChanged(object)", state
|
||||
|
||||
@@ -171,16 +179,12 @@ class ButtonArea(QWidget):
|
||||
self.show_only_label_properties("")
|
||||
self.stateChanged.emit(self.get_current_state())
|
||||
|
||||
|
||||
def load(self, config_filepath):
|
||||
execfile(config_filepath)
|
||||
self.init_button_lists()
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
from conf import config
|
||||
config.update("example_config")
|
||||
|
||||
ba = ButtonArea()
|
||||
ba.load("example_config.py")
|
||||
app = QApplication(sys.argv)
|
||||
ba = ButtonArea(config.LABELS, config.HOTKEYS)
|
||||
ba.show()
|
||||
|
||||
return app.exec_()
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from conf import default_config
|
||||
import importlib
|
||||
|
||||
class Config:
|
||||
def __init__(self):
|
||||
# init the configuration with the default config
|
||||
for setting in dir(default_config):
|
||||
if setting == setting.upper():
|
||||
setattr(self, setting, getattr(default_config, setting))
|
||||
|
||||
def update(self, module_path):
|
||||
try:
|
||||
mod = importlib.import_module(module_path)
|
||||
except ImportError, e:
|
||||
raise ImportError("Could not import configuration '%s' (Is it on sys.path?): %s" % (module_path, e))
|
||||
|
||||
for setting in dir(mod):
|
||||
if setting == setting.upper():
|
||||
setting_value = getattr(mod, setting)
|
||||
setattr(self, setting, setting_value)
|
||||
|
||||
config = Config()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
LABELS = (
|
||||
)
|
||||
|
||||
HOTKEYS = (
|
||||
)
|
||||
|
||||
ITEMS = (
|
||||
("rect", "items.RectItem", "items.RectItemInserter"),
|
||||
("point", "items.PointItem", "items.PointItemInserter")
|
||||
)
|
||||
|
||||
INSERTERS = (
|
||||
)
|
||||
|
||||
LOADERS = (
|
||||
)
|
||||
|
||||
PLUGINS = (
|
||||
)
|
||||
|
||||
+22
-18
@@ -4,22 +4,26 @@ obj_type_choice2 = ["Peach", "Table", "Window"]
|
||||
ID_choice = ["Martin", "Mika", "Alexander", "Lukas", "Tobias"]
|
||||
ID_choice2 = ["Boris", "Manel", "Rainer", "Hua", "Hazim"]
|
||||
|
||||
self.add_label("Head", {"type": "rect",
|
||||
"class": "head",
|
||||
"id": ID_choice})
|
||||
self.add_label("Left Eye", {"type": "point",
|
||||
"class": "left_eye",
|
||||
"id": ID_choice,
|
||||
"obj_type": obj_type_choice})
|
||||
self.add_label("Right Eye", {"type": "point",
|
||||
"class": "right_eye",
|
||||
"id": ID_choice2,
|
||||
"obj_type": obj_type_choice2})
|
||||
self.add_label("Left Hand", {"type": "rect",
|
||||
"class": "left_hand",
|
||||
"obj_type": obj_type_choice})
|
||||
self.add_label("Right Hand", {"type": "rect",
|
||||
"class": "right_hand"})
|
||||
LABELS = (
|
||||
("Head", {"type": "rect",
|
||||
"class": "head",
|
||||
"id": ID_choice}),
|
||||
("Left Eye", {"type": "point",
|
||||
"class": "left_eye",
|
||||
"id": ID_choice,
|
||||
"obj_type": obj_type_choice}),
|
||||
("Right Eye", {"type": "point",
|
||||
"class": "right_eye",
|
||||
"id": ID_choice2,
|
||||
"obj_type": obj_type_choice2}),
|
||||
("Left Hand", {"type": "rect",
|
||||
"class": "left_hand",
|
||||
"obj_type": obj_type_choice}),
|
||||
("Right Hand", {"type": "rect",
|
||||
"class": "right_hand"}),
|
||||
)
|
||||
|
||||
self.add_hotkey("", "Head", "h")
|
||||
self.add_hotkey("id", "Martin", "CTRL+m")
|
||||
HOTKEYS = (
|
||||
("", "Head", "h"),
|
||||
("id", "Martin", "CTRL+m"),
|
||||
)
|
||||
|
||||
+27
-17
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
import sys, os
|
||||
import functools
|
||||
import functools, importlib
|
||||
from PyQt4.QtGui import *
|
||||
from PyQt4.QtCore import *
|
||||
import PyQt4.uic as uic
|
||||
@@ -9,18 +9,28 @@ from buttonarea import *
|
||||
from annotationmodel import *
|
||||
from annotationscene import *
|
||||
from frameviewer import *
|
||||
from loaders import *
|
||||
from optparse import OptionParser
|
||||
import annotations
|
||||
|
||||
from conf import config
|
||||
|
||||
APP_NAME = """labeltool"""
|
||||
ORGANIZATION_NAME = """CVHCI Research Group"""
|
||||
ORGANIZATION_DOMAIN = """cvhci.anthropomatik.kit.edu"""
|
||||
__version__ = """0.1"""
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
def __init__(self, argv, parent=None):
|
||||
super(MainWindow, self).__init__(parent)
|
||||
|
||||
# parse command line options
|
||||
options, args = self.parseCommandLineOptions(argv)
|
||||
if options.config != "":
|
||||
# load config
|
||||
config.update(options.config)
|
||||
|
||||
self.loaders_ = []
|
||||
|
||||
self.anno_container = annotations.AnnotationContainer()
|
||||
self.current_index_ = None
|
||||
|
||||
@@ -30,26 +40,33 @@ class MainWindow(QMainWindow):
|
||||
self.updateStatus()
|
||||
self.updateViews()
|
||||
|
||||
if len(argv) > 0:
|
||||
self.loadInitialFile(argv[0])
|
||||
if len(args) > 0:
|
||||
self.loadInitialFile(args[0])
|
||||
else:
|
||||
self.loadInitialFile()
|
||||
|
||||
def parseCommandLineOptions(self, argv):
|
||||
usage = "Usage: %prog [-c config.py] [annotation_file]"
|
||||
version = "%prog " + __version__
|
||||
|
||||
parser = OptionParser(usage=usage, version=version)
|
||||
parser.add_option("-c", "--config", action="store", type="string", default="", help="Configuration file.")
|
||||
|
||||
return parser.parse_args(argv)
|
||||
|
||||
###
|
||||
### GUI/Application setup
|
||||
###___________________________________________________________________________________________
|
||||
def setupGui(self):
|
||||
self.ui = uic.loadUi("labeltool.ui", self)
|
||||
|
||||
self.scene = AnnotationScene(self)
|
||||
self.scene = AnnotationScene(items=config.ITEMS, inserters=config.INSERTERS)
|
||||
self.view = GraphicsView(self)
|
||||
self.view.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
|
||||
self.view.setScene(self.scene)
|
||||
self.setCentralWidget(self.view)
|
||||
|
||||
self.buttonarea = ButtonArea()
|
||||
# TODO make this configurable/settable via command line option
|
||||
self.buttonarea.load("std_config.py")
|
||||
self.buttonarea = ButtonArea(config.LABELS, config.HOTKEYS)
|
||||
self.ui.dockAnnotationButtons.setWidget(self.buttonarea)
|
||||
self.buttonarea.stateChanged.connect(self.scene.setMode)
|
||||
|
||||
@@ -58,14 +75,6 @@ class MainWindow(QMainWindow):
|
||||
self.treeview.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
self.ui.dockInformation.setWidget(self.treeview)
|
||||
|
||||
## create action group for tools
|
||||
self.toolActions = QActionGroup(self)
|
||||
for action in (self.ui.actionSelection,
|
||||
self.ui.actionPoint,
|
||||
self.ui.actionRectangle,
|
||||
self.ui.actionMask):
|
||||
self.toolActions.addAction(action)
|
||||
|
||||
self.ui.show()
|
||||
|
||||
## connect action signals
|
||||
@@ -106,6 +115,7 @@ class MainWindow(QMainWindow):
|
||||
filename = QVariant()
|
||||
settings.setValue("LastFile", filename)
|
||||
|
||||
|
||||
###
|
||||
### Annoation file handling
|
||||
###___________________________________________________________________________________________
|
||||
|
||||
+45
-7
@@ -1,10 +1,48 @@
|
||||
from items import AnnotationGraphicsRectItem as RectItem
|
||||
from items import RectItemInserter
|
||||
from bboxitem import *
|
||||
|
||||
RATIOS = ["0.5", "1", "2"]
|
||||
|
||||
self.add_label("Rect", {"type": "rect"})
|
||||
self.add_label("FixedRatioRect", {"type": "ratiorect", "_ratio": RATIOS})
|
||||
self.add_label("Point", {"type": "point"})
|
||||
self.add_label("Polygon", {"type": "polygon"})
|
||||
LABELS = (
|
||||
("Rect", {"type" : "rect"}),
|
||||
("FixedRatioRect", {"type": "ratiorect", "_ratio": RATIOS}),
|
||||
("Point", {"type": "point"}),
|
||||
("Polygon", {"type": "polygon"}),
|
||||
("BodyBBox", {"type": "bodybbox"}),
|
||||
)
|
||||
|
||||
HOTKEYS = (
|
||||
("", "Rect", "r"),
|
||||
("", "Point", "p"),
|
||||
("", "Polygon", "o"),
|
||||
("", "BodyBBox", "b")
|
||||
)
|
||||
|
||||
ITEMS = (
|
||||
("rect", RectItem),
|
||||
("bodybbox", BodyBoundingboxItem),
|
||||
)
|
||||
|
||||
INSERTERS = (
|
||||
("rect", RectItemInserter),
|
||||
("bodybbox", BodyBoundingboxItemInserter),
|
||||
)
|
||||
|
||||
LOADERS = (
|
||||
)
|
||||
|
||||
PLUGINS = (
|
||||
)
|
||||
|
||||
#labeltool.buttonarea.add_label("Rect", {"type": "rect"})
|
||||
#labeltool.buttonarea.add_label("FixedRatioRect", {"type": "ratiorect", "_ratio": RATIOS})
|
||||
#labeltool.buttonarea.add_label("Point", {"type": "point"})
|
||||
#labeltool.buttonarea.add_label("Polygon", {"type": "polygon"})
|
||||
#labeltool.buttonarea.add_label("BodyBBox", {"type": "bodybbox"})
|
||||
#
|
||||
#Labeltool.buttonarea.add_hotkey("", "Rect", "r")
|
||||
#Labeltool.buttonarea.add_hotkey("", "Point", "p")
|
||||
#Labeltool.buttonarea.add_hotkey("", "Polygon", "o")
|
||||
#Labeltool.buttonarea.add_hotkey("", "BodyBBox", "b")
|
||||
|
||||
self.add_hotkey("", "Rect", "r")
|
||||
self.add_hotkey("", "Point", "p")
|
||||
self.add_hotkey("", "Polygon", "o")
|
||||
|
||||
Reference in New Issue
Block a user