#export
class BBoxVideoAnnotator(BBoxAnnotator):
def __init__(self, *args, **kwargs):
super().__init__(*args, **{**kwargs, 'render_previous_coords': False})
pub.unsubscribe(self.controller._idx_changed, f'{self.app_state.root_topic}.index')
pub.unsubAll(f'{self.app_state.root_topic}.index')
state_params = {**self.bbox_state.dict()}
state_params.pop('_uuid', [])
state_params.pop('event_map', [])
self.bbox_state = BBoxVideoState(
uuid=self.bbox_state._uuid,
**state_params
)
self.controller = BBoxVideoAnnotatorController(
app_state=self.app_state,
bbox_state=self.bbox_state,
storage=self.storage
)
self.view = BBoxAnnotatorVideoGUI(
app_state=self.app_state,
bbox_state=self.bbox_state,
on_save_btn_clicked=self.on_save_btn_clicked,
drawing_enabled=self._output_item.drawing_enabled,
on_label_changed=self.update_labels,
on_join_btn_clicked=self.merge_tracks_selected,
on_bbox_drawn=self.controller.sync_labels,
fit_canvas=self._input_item.fit_canvas
)
self.view.on_client_ready(self.controller.handle_client_ready)
def update_labels(self, change: dict, index: int):
"""Saves bbox_canvas_state coordinates data
on bbox_state and save all on storage."""
self.bbox_state.set_quietly('coords', self.view._image_box._state.bbox_coords)
# "BBoxAnnotatorController" has no attribute "update_storage_labels"
self.controller.update_storage_labels(change, index) # type: ignore
def on_save_btn_clicked(self, bbox_coords: List[BboxVideoCoordinate]):
self.controller.save_current_annotations(bbox_coords) # type: ignore
def _update_state_id(self, merged_ids: List[str], bbox_coords: List[BboxVideoCoordinate]):
merged_id = "-".join(merged_ids)
for i, coord in enumerate(bbox_coords):
if merged_id and bbox_coords[i].id in merged_ids:
bbox_coords[i].id = merged_id
def merge_tracks_selected(self, change: Dict):
# "BBoxState" has no attribute "bbox_coords_selected"
selecteds = self.bbox_state.bbox_coords_selected # type: ignore
if selecteds:
merged_ids = [selected.bbox_video_coordinate.id for selected in selecteds]
self._update_state_id(
# Argument "bbox_coords" to "_update_state_id" of "BBoxVideoAnnotator" has
#incompatible type "List[BboxCoordinate]"; expected "List[BboxVideoCoordinate]"
merged_ids=merged_ids, # type: ignore
bbox_coords=self.view._image_box.state.bbox_coords # type: ignore
)
# "BBoxAnnotatorController" has no attribute "update_storage_id"
self.controller.update_storage_id( # type: ignore
merged_ids=merged_ids
)
# merge trajectories
key = "-".join(merged_ids)
# "BBoxState" has no attribute "trajectory"
tmp_trajectories = deepcopy(self.bbox_state.trajectories) # type: ignore
for id, bbx in tmp_trajectories.items():
if id in merged_ids:
try:
self.bbox_state.trajectories[key] += bbx # type: ignore
except Exception:
self.bbox_state.trajectories[key] = bbx # type: ignore
if id in self.bbox_state.trajectories: # type: ignore
# delete old trajectory id
del self.bbox_state.trajectories[id] # type: ignore
# finished merge cleans selected bbox coords
self.bbox_state.bbox_coords_selected = []
self.view.clear_right_menu()
self.view.render_right_menu(self.view._image_box.state.bbox_coords)