Release 0.5 (#705)

* Changed version number (0, 5, 'final', 0).
* Updated changelog file.
* fixed default attribute values for tracked shapes (#703)
main
Nikita Manovich 7 years ago committed by GitHub
parent 8359db3580
commit 38cf6d4a56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [0.5.0] - 2019-10-12
### Added ### Added
- A converter to YOLO format - A converter to YOLO format
- Installation guide - Installation guide
@ -20,13 +20,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added in a command line model manager tester - Added in a command line model manager tester
- Ability to dump/load annotations in several formats from UI (CVAT, Pascal VOC, YOLO, MS COCO, png mask, TFRecord) - Ability to dump/load annotations in several formats from UI (CVAT, Pascal VOC, YOLO, MS COCO, png mask, TFRecord)
- Auth for REST API (api/v1/auth/): login, logout, register, ... - Auth for REST API (api/v1/auth/): login, logout, register, ...
- Preview for the new CVAT UI (dashboard only) is available: http://localhost:9080/
### Changed ### Changed
- Outside and keyframe buttons in the side panel for all interpolation shapes (they were only for boxes before) - Outside and keyframe buttons in the side panel for all interpolation shapes (they were only for boxes before)
- Improved error messages on client side (#511) - Improved error messages on the client side (#511)
### Deprecated
-
### Removed ### Removed
- "Flip images" has been removed. UI now contains rotation features. - "Flip images" has been removed. UI now contains rotation features.
@ -49,7 +47,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Creating a video task with 0 overlap - Creating a video task with 0 overlap
### Security ### Security
- - Upgraded Django, djangorestframework, and other packages
## [0.4.2] - 2019-06-03 ## [0.4.2] - 2019-06-03
### Fixed ### Fixed

@ -5,6 +5,6 @@
from cvat.utils.version import get_version from cvat.utils.version import get_version
VERSION = (0, 5, 0, 'alpha', 0) VERSION = (0, 5, 0, 'final', 0)
__version__ = get_version(VERSION) __version__ = get_version(VERSION)

@ -21,6 +21,14 @@ from .data_manager import DataManager
from .log import slogger from .log import slogger
from . import serializers from . import serializers
"""dot.notation access to dictionary attributes"""
class dotdict(OrderedDict):
__getattr__ = OrderedDict.get
__setattr__ = OrderedDict.__setitem__
__delattr__ = OrderedDict.__delitem__
__eq__ = lambda self, other: self.id == other.id
__hash__ = lambda self: self.id
class PatchAction(str, Enum): class PatchAction(str, Enum):
CREATE = "create" CREATE = "create"
UPDATE = "update" UPDATE = "update"
@ -142,15 +150,6 @@ def bulk_create(db_model, objects, flt_param):
return [] return []
def _merge_table_rows(rows, keys_for_merge, field_id): def _merge_table_rows(rows, keys_for_merge, field_id):
"""dot.notation access to dictionary attributes"""
from collections import OrderedDict
class dotdict(OrderedDict):
__getattr__ = OrderedDict.get
__setattr__ = OrderedDict.__setitem__
__delattr__ = OrderedDict.__delitem__
__eq__ = lambda self, other: self.id == other.id
__hash__ = lambda self: self.id
# It is necessary to keep a stable order of original rows # It is necessary to keep a stable order of original rows
# (e.g. for tracked boxes). Otherwise prev_box.frame can be bigger # (e.g. for tracked boxes). Otherwise prev_box.frame can be bigger
# than next_box.frame. # than next_box.frame.
@ -202,12 +201,16 @@ class JobAnnotation:
"all": OrderedDict(), "all": OrderedDict(),
} }
for db_attr in db_label.attributespec_set.all(): for db_attr in db_label.attributespec_set.all():
default_value = dotdict([
('spec_id', db_attr.id),
('value', db_attr.default_value),
])
if db_attr.mutable: if db_attr.mutable:
self.db_attributes[db_label.id]["mutable"][db_attr.id] = db_attr self.db_attributes[db_label.id]["mutable"][db_attr.id] = default_value
else: else:
self.db_attributes[db_label.id]["immutable"][db_attr.id] = db_attr self.db_attributes[db_label.id]["immutable"][db_attr.id] = default_value
self.db_attributes[db_label.id]["all"][db_attr.id] = db_attr self.db_attributes[db_label.id]["all"][db_attr.id] = default_value
def reset(self): def reset(self):
self.ir_data.reset() self.ir_data.reset()
@ -458,13 +461,13 @@ class JobAnnotation:
self._commit() self._commit()
@staticmethod @staticmethod
def _extend_attributes(attributeval_set, attribute_specs): def _extend_attributes(attributeval_set, default_attribute_values):
shape_attribute_specs_set = set(attr.spec_id for attr in attributeval_set) shape_attribute_specs_set = set(attr.spec_id for attr in attributeval_set)
for db_attr_spec in attribute_specs: for db_attr in default_attribute_values:
if db_attr_spec.id not in shape_attribute_specs_set: if db_attr.spec_id not in shape_attribute_specs_set:
attributeval_set.append(OrderedDict([ attributeval_set.append(dotdict([
('spec_id', db_attr_spec.id), ('spec_id', db_attr.spec_id),
('value', db_attr_spec.default_value), ('value', db_attr.value),
])) ]))
def _init_tags_from_db(self): def _init_tags_from_db(self):
@ -600,12 +603,16 @@ class JobAnnotation:
self._extend_attributes(db_track.labeledtrackattributeval_set, self._extend_attributes(db_track.labeledtrackattributeval_set,
self.db_attributes[db_track.label_id]["immutable"].values()) self.db_attributes[db_track.label_id]["immutable"].values())
default_attribute_values = self.db_attributes[db_track.label_id]["mutable"].values()
for db_shape in db_track["trackedshape_set"]: for db_shape in db_track["trackedshape_set"]:
db_shape["trackedshapeattributeval_set"] = list( db_shape["trackedshapeattributeval_set"] = list(
set(db_shape["trackedshapeattributeval_set"]) set(db_shape["trackedshapeattributeval_set"])
) )
self._extend_attributes(db_shape["trackedshapeattributeval_set"], # in case of trackedshapes need to interpolate attriute values and extend it
self.db_attributes[db_track.label_id]["mutable"].values()) # by previous shape attribute values (not default values)
self._extend_attributes(db_shape["trackedshapeattributeval_set"], default_attribute_values)
default_attribute_values = db_shape["trackedshapeattributeval_set"]
serializer = serializers.LabeledTrackSerializer(db_tracks, many=True) serializer = serializers.LabeledTrackSerializer(db_tracks, many=True)
self.ir_data.tracks = serializer.data self.ir_data.tracks = serializer.data

Loading…
Cancel
Save