Skip to content

Commit 38cf6d4

Browse files
authored
Release 0.5 (#705)
* Changed version number (0, 5, 'final', 0). * Updated changelog file. * fixed default attribute values for tracked shapes (#703)
1 parent 8359db3 commit 38cf6d4

File tree

3 files changed

+32
-27
lines changed

3 files changed

+32
-27
lines changed

CHANGELOG.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased]
7+
## [0.5.0] - 2019-10-12
88
### Added
99
- A converter to YOLO format
1010
- Installation guide
@@ -20,13 +20,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020
- Added in a command line model manager tester
2121
- Ability to dump/load annotations in several formats from UI (CVAT, Pascal VOC, YOLO, MS COCO, png mask, TFRecord)
2222
- Auth for REST API (api/v1/auth/): login, logout, register, ...
23+
- Preview for the new CVAT UI (dashboard only) is available: http://localhost:9080/
2324

2425
### Changed
2526
- Outside and keyframe buttons in the side panel for all interpolation shapes (they were only for boxes before)
26-
- Improved error messages on client side (#511)
27-
28-
### Deprecated
29-
-
27+
- Improved error messages on the client side (#511)
3028

3129
### Removed
3230
- "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
4947
- Creating a video task with 0 overlap
5048

5149
### Security
52-
-
50+
- Upgraded Django, djangorestframework, and other packages
5351

5452
## [0.4.2] - 2019-06-03
5553
### Fixed

cvat/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@
55

66
from cvat.utils.version import get_version
77

8-
VERSION = (0, 5, 0, 'alpha', 0)
8+
VERSION = (0, 5, 0, 'final', 0)
99

1010
__version__ = get_version(VERSION)

cvat/apps/engine/annotation.py

+27-20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@
2121
from .log import slogger
2222
from . import serializers
2323

24+
"""dot.notation access to dictionary attributes"""
25+
class dotdict(OrderedDict):
26+
__getattr__ = OrderedDict.get
27+
__setattr__ = OrderedDict.__setitem__
28+
__delattr__ = OrderedDict.__delitem__
29+
__eq__ = lambda self, other: self.id == other.id
30+
__hash__ = lambda self: self.id
31+
2432
class PatchAction(str, Enum):
2533
CREATE = "create"
2634
UPDATE = "update"
@@ -142,15 +150,6 @@ def bulk_create(db_model, objects, flt_param):
142150
return []
143151

144152
def _merge_table_rows(rows, keys_for_merge, field_id):
145-
"""dot.notation access to dictionary attributes"""
146-
from collections import OrderedDict
147-
class dotdict(OrderedDict):
148-
__getattr__ = OrderedDict.get
149-
__setattr__ = OrderedDict.__setitem__
150-
__delattr__ = OrderedDict.__delitem__
151-
__eq__ = lambda self, other: self.id == other.id
152-
__hash__ = lambda self: self.id
153-
154153
# It is necessary to keep a stable order of original rows
155154
# (e.g. for tracked boxes). Otherwise prev_box.frame can be bigger
156155
# than next_box.frame.
@@ -202,12 +201,16 @@ def __init__(self, pk, user):
202201
"all": OrderedDict(),
203202
}
204203
for db_attr in db_label.attributespec_set.all():
204+
default_value = dotdict([
205+
('spec_id', db_attr.id),
206+
('value', db_attr.default_value),
207+
])
205208
if db_attr.mutable:
206-
self.db_attributes[db_label.id]["mutable"][db_attr.id] = db_attr
209+
self.db_attributes[db_label.id]["mutable"][db_attr.id] = default_value
207210
else:
208-
self.db_attributes[db_label.id]["immutable"][db_attr.id] = db_attr
211+
self.db_attributes[db_label.id]["immutable"][db_attr.id] = default_value
209212

210-
self.db_attributes[db_label.id]["all"][db_attr.id] = db_attr
213+
self.db_attributes[db_label.id]["all"][db_attr.id] = default_value
211214

212215
def reset(self):
213216
self.ir_data.reset()
@@ -458,13 +461,13 @@ def delete(self, data=None):
458461
self._commit()
459462

460463
@staticmethod
461-
def _extend_attributes(attributeval_set, attribute_specs):
464+
def _extend_attributes(attributeval_set, default_attribute_values):
462465
shape_attribute_specs_set = set(attr.spec_id for attr in attributeval_set)
463-
for db_attr_spec in attribute_specs:
464-
if db_attr_spec.id not in shape_attribute_specs_set:
465-
attributeval_set.append(OrderedDict([
466-
('spec_id', db_attr_spec.id),
467-
('value', db_attr_spec.default_value),
466+
for db_attr in default_attribute_values:
467+
if db_attr.spec_id not in shape_attribute_specs_set:
468+
attributeval_set.append(dotdict([
469+
('spec_id', db_attr.spec_id),
470+
('value', db_attr.value),
468471
]))
469472

470473
def _init_tags_from_db(self):
@@ -600,12 +603,16 @@ def _init_tracks_from_db(self):
600603
self._extend_attributes(db_track.labeledtrackattributeval_set,
601604
self.db_attributes[db_track.label_id]["immutable"].values())
602605

606+
default_attribute_values = self.db_attributes[db_track.label_id]["mutable"].values()
603607
for db_shape in db_track["trackedshape_set"]:
604608
db_shape["trackedshapeattributeval_set"] = list(
605609
set(db_shape["trackedshapeattributeval_set"])
606610
)
607-
self._extend_attributes(db_shape["trackedshapeattributeval_set"],
608-
self.db_attributes[db_track.label_id]["mutable"].values())
611+
# in case of trackedshapes need to interpolate attriute values and extend it
612+
# by previous shape attribute values (not default values)
613+
self._extend_attributes(db_shape["trackedshapeattributeval_set"], default_attribute_values)
614+
default_attribute_values = db_shape["trackedshapeattributeval_set"]
615+
609616

610617
serializer = serializers.LabeledTrackSerializer(db_tracks, many=True)
611618
self.ir_data.tracks = serializer.data

0 commit comments

Comments
 (0)