def _set_widgets(self): self.view = BufferRenderView(width=self.width, height=self.height, video_player=self) self.view.rect_changed.connect(lambda packet: self.rect_changed.emit( SignalPacket(sender=[*packet.sender, self.__class__.__name__], data=packet.data))) self.view.req_datahandler_info.connect( self._request_datahandler_info_sl) self.view.prop_data_change.connect( lambda packet: self.prop_data_change.emit( SignalPacket(sender=[*packet.sender, self.__class__.__name__], data=packet.data))) # self.frames_id_label = qtw.QLabel( # f'<font color="green">-</font> ' # f'<b>/</b> ' # f'<font color="red">{str(self.frame_max)}</font> \n' # ) self.frames_id_label = qtw.QLabel() self._set_frames_info("-") self.backward_btn = qtw.QPushButton() self.slider = qtw.QSlider(qtc.Qt.Horizontal) self.start_pause_btn = qtw.QToolButton()
def propogate_curr_frame_data_sl(self, packet: SignalPacket): # TODO: check the best way to pass ndarray self.curr_frame, self.curr_index = packet.data framedata = FrameData(self.curr_frame, self.curr_index, self.from_frame(self.curr_index)) self.curr_frame_data.emit( SignalPacket(sender=self.__class__.__name__, data=framedata) )
def test_delete_instance(self, svv, s_tobj_instance_l): delete = s_tobj_instance_l.track_id, len(s_tobj_instance_l) // 2 iv = svv.get(s_tobj_instance_l.object_class) prev_lm = iv.labels_mapping() prev_label = iv.labels_mapping(delete[0]) prev_len = len(iv[prev_label]["image_buttons"]) dui = DataUpdateInfo(deleted=delete) svv.data_update_sl(SignalPacket(sender="dummy", data=dui)) curr_lm = iv.labels_mapping() curr_label = iv.labels_mapping(delete[0]) if prev_len != 1: curr_len = len(iv[prev_label]["image_buttons"]) if prev_len == 1: # Deleted a row... assert all([ len(prev_lm) - 1 == len(curr_lm), all([ curr_lm[i][0] + 1 == curr_lm[i + 1][0] for i in range(len(curr_lm) - 1) ]) ]) else: assert all([curr_label == prev_label, curr_len == prev_len - 1])
def test_run_results_r_error(data_handler, frame_id, n_ins): instances = data_handler.from_frame(frame_id) instances.append(Instance(100, "dummy", 100, 1, 2, 1, 2, None)) sp = SignalPacket("dummy", instances) with pytest.raises(Exception): data_handler.run_slesults_sl(sp)
def test_insert_one_tracked_obj_with_one_instance(self, data_handler, svv, s_tobj_l, qtbot): tobj = deepcopy(s_tobj_l) if tobj.track_id == 0: tobj.change_track_id(1) tobj.object_class = data_handler[1].object_class else: tobj.change_track_id(0) tobj.object_class = data_handler[0].object_class dui = DataUpdateInfo(added=tobj) svv.data_update_sl(SignalPacket(sender="dummy", data=dui)) for iv in svv: idx = iv.labels_mapping(tobj.track_id) if idx is not None: break # since basically `data_handler` used `s_tobj_l` img_btns = iv[idx]["image_buttons"] assert all([ len(img_btns) == 1, img_btns[tobj[0].instance_id].x1 == tobj[0].x1, img_btns[tobj[0].instance_id].y1 == tobj[0].y1, img_btns[tobj[0].instance_id].x2 == tobj[0].x2, img_btns[tobj[0].instance_id].y2 == tobj[0].y2, ])
def test_add_instance(bbs, s_tobj_l): prev_len = len(bbs.get_tobj(s_tobj_l.track_id)) bbs.add_instance_sl(SignalPacket(sender="dummy", data=s_tobj_l)) assert all([ len(bbs.get_tobj(s_tobj_l.track_id)) == prev_len + 1, bbs.get_tobj(s_tobj_l.track_id)[-1] == s_tobj_l[0] ])
def test_slun_slesults_sl(data_handler, frame_id, n_ins): instances = data_handler.from_frame(frame_id) prev_len = len(instances) sp = SignalPacket("dummy", instances) data_handler.run_slesults_sl(sp) assert len(instances) == prev_len
def mouseReleaseEvent(self, event): super().mouseReleaseEvent(event) if self.draw_box: self.req_datahandler_info.emit( SignalPacket(sender=[self.__class__.__name__], data=(None, None))) self.draw_box = False self.update_frame()
def on_rect_change(self, track_id, instance_id, x1, y1, x2, y2): dui = DataUpdateInfo(replaced=dict(track_id=track_id, instance_id=instance_id, x1=x1, y1=y1, x2=x2, y2=y2)) self.rect_changed.emit( SignalPacket(sender=[self.__class__.__name__], data=dui))
def delete(self, tobj_idx: int, instance_idx: int = None): self._delete(tobj_idx, instance_idx) dui = DataUpdateInfo(deleted=(tobj_idx, instance_idx)) self.data_updated.emit( SignalPacket(sender=self.__class__.__name__, data=dui) ) return self
def get_frame(self, idx, straight_jump=False): self.idx = idx self.video.set(cv2.CAP_PROP_POS_FRAMES, self.idx) if straight_jump: self.curr_frame.emit( SignalPacket(sender="Buffer", data=(self.next_frame().copy(), self.idx))) else: return self.next_frame()
def test_receive_curr_FrameData(brv, m_buffer, data_handler, s_tobj_instance_l): dummy_frame = np.zeros([60, 60, 3], np.uint8) dummy_idx = 2 data_handler.curr_frame_data.connect(brv.set_frame_data_r) data_handler.propogate_curr_frame_data_sl( SignalPacket("dummy", (dummy_frame, dummy_idx))) assert all([ brv.curr_frame.shape == dummy_frame.shape, all([i == j for i, j in zip(brv.curr_data, s_tobj_instance_l)]) ])
def add(self, obj: Union[Instance, TrackedObject], image: Optional[np.ndarray] = None): self._add(obj, image) if isinstance(obj, TrackedObject): frame_ids = [ins.frame_id for ins in obj] elif isinstance(obj, Instance): frame_ids = [obj.frame_id] self.req_frames.emit( SignalPacket(sender=[self.__class__.__name__], data=frame_ids))
def data_update_sl(self, packet: SignalPacket): dui: DataUpdateInfo = packet.data # We just consider for an Instance object to # other Instance or new TrackedObject if dui.added: self.add(dui.added) elif dui.deleted: pos: Tuple[int, int] = dui.deleted self.delete(*pos) # TODO: How to delete object?? elif dui.replaced: self.replace(dui.replaced) elif dui.moved: self.move(*dui.moved) self._update() try: # Assuming every data added and deleted is through this function, # this will make sure our viewport is also updated. framedata = FrameData(self.curr_frame, self.curr_index, self.from_frame(self.curr_index)) self.curr_frame_data.emit( SignalPacket(sender=[*packet.sender, self.__class__.__name__], data=framedata) ) except NameError: # Haven't even started the buffer yet... pass # TODO: This determines autosave feature. # However, only valid on change based on slot. Make it better. self.change_count += 1 if self.change_count >= self.autosave_step: self.save() self.change_count = 0 self.print_data.emit( SignalPacket(sender=[self.__class__.__name__], data=self.__str__()) )
def _set_attributes(self): """Set internal attributes of the view.""" self.setAlignment(qtc.Qt.AlignTop | qtc.Qt.AlignLeft) self.setSizePolicy(qtw.QSizePolicy.Fixed, qtw.QSizePolicy.Fixed) self.setHorizontalScrollBarPolicy(qtc.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(qtc.Qt.ScrollBarAlwaysOff) self.setAcceptDrops(True) # self.setScene(qtw.QGraphicsScene()) scene = VideoBufferScene() scene.rect_changed.connect(lambda packet: self.rect_changed.emit( SignalPacket(sender=[*packet, self.__class__.__name__], data=packet.data))) self.setScene(scene)
def test_session_init(self, qtbot, data_handler, s_tobj_l, buff): # stimulate new data... new_t_id = len(data_handler) for _ in len(s_tobj_l) - 1: s_tobj_l.delete(0) s_tobj_l.change_track_id(n_t_id) sp = SignalPacket("dummy", s_tobj_l) with qtbot.wait_signal(buff.session_initialized) as blocker: buff.session_init_sl(sp) assert blocker.args[0].data == sp
def test_init_session_tobj(edh, s_tobj_l): tobj = deepcopy(s_tobj_l) while len(tobj) != 1: tobj.delete(-1) if tobj.track_id != 0: tobj.change_track_id(0) bbs = BBSession(edh) # bbs.added_tobj.connect(edh.add_r) bbs.add_tobj_sl(SignalPacket(sender="dummy", data=tobj)) assert all([ len(edh) == 1, edh[0] == tobj, ])
def replace(self, instance: Union[Instance, dict]): if isinstance(instance, dict): pos = ["track_id", "instance_id"] t_id, ins_id = instance[pos[0]], instance[pos[1]] new = deepcopy(self[t_id][ins_id]) for key in instance: if key not in pos: setattr(new, key, instance[key]) instance = new self._replace(instance) dui = DataUpdateInfo(replaced=instance) self.data_updated.emit( SignalPacket(sender=self.__class__.__name__, data=dui) )
def test_delete_tobj(self, svv, s_tobj_instance_l): delete = s_tobj_instance_l.track_id, None iv = svv.get(s_tobj_instance_l.object_class) prev_lm = iv.labels_mapping() prev_label = iv.labels_mapping(delete[0]) dui = DataUpdateInfo(deleted=delete) svv.data_update_sl(SignalPacket(sender="dummy", data=dui)) curr_lm = iv.labels_mapping() curr_label = iv.labels_mapping(delete[0]) assert all([ len(prev_lm) == len(curr_lm) + 1, ])
def _edit(self, pos: Tuple[int, int], new_obj: Union[Instance, TrackedObject]): self._delete_instance(*pos, emit_signal=False) if isinstance(new_obj, TrackedObject): self._add_tobj(new_obj, emit_signal=False) elif isinstance(new_obj, Instance): self._add_instance(new_instance, emit_signal=False) else: raise ValueError(f"Do not support data of type {type(new_obj)}") # self.edited_instance.emit( # SignalPacket(sender=self.__class__.__name__, data=(pos, new_obj)) # ) dui = DataUpdateInfo(edit=(pos, new_obj)) self.data_updated.emit( SignalPacket(sender=self.__class__.__name__, data=dui) ) return self
def accept(self): data = self._make_new_data() if self.add_only: data.instance_id = -1 dui = DataUpdateInfo(added=data) else: if isinstance( data, TrackedObject) or data.track_id != self.instance.track_id: dui = DataUpdateInfo(moved=((self.instance.track_id, self.instance.instance_id), data)) else: dui = DataUpdateInfo(replaced=data) self.prop_data_change.emit( SignalPacket(sender=[self.__class__.__name__], data=dui)) super().accept()
def move(self, old_pos, obj: Union[TrackedObject, Instance]): prev_len = len(self) self._delete_instance(*old_pos) # TODO: There must be a better way... if old_pos[0] <= obj.track_id and prev_len == len(self) + 1: try: obj.change_track_id(obj.track_id - 1) except AttributeError: obj.track_id -= 1 if isinstance(obj, TrackedObject): self._add_tobj(obj) else: self._add_instance(obj) dui = DataUpdateInfo(moved=(old_pos, obj)) self.data_updated.emit( SignalPacket(sender=self.__class__.__name__, data=dui) )
def test_append_one_instance(self, data_handler, svv, s_tobj_l, qtbot): instance = deepcopy(s_tobj_l[0]) instance.instance_id = len(data_handler[instance.track_id]) dui = DataUpdateInfo(added=instance) svv.data_update_sl(SignalPacket(sender="dummy", data=dui)) for iv in svv: idx = iv.labels_mapping(instance.track_id) if idx is not None: break # since basically `data_handler` used `s_tobj_l` img_btns = iv[idx]["image_buttons"] assert all([ len(img_btns) == len(data_handler[instance.track_id]) + 1, img_btns[instance.instance_id].x1 == instance.x1, img_btns[instance.instance_id].y1 == instance.y1, img_btns[instance.instance_id].x2 == instance.x2, img_btns[instance.instance_id].y2 == instance.y2, ])
def init_data(self, data_handler: DataHandler): # Signal must be connected for image acquisitions. tobjs = data_handler[:] obj_cls_tobjs = defaultdict(list) for tobj in tobjs: obj_cls_tobjs[tobj.object_class].append(tobj) for oc in data_handler.object_classes: imv = ImagesViewerView(name=oc) imv.req_instance.connect(self.request_data_sl) imv.req_frames.connect(self.request_frames_sl) imv.jump_to_frame.connect(self._jump_to_frame_sl) self.view._add_images_viewer(oc, imv) for name, images_viewer in self.view._images_viewers.items(): images_viewer.init_data(obj_cls_tobjs[name]) self.req_frames.emit( SignalPacket(sender=[self.__class__.__name__], data=self.frame_ids) )
def add(self, data: Union[TrackedObject, Instance, List[Instance]]): """Add data. The passed data should already have `track_id` and `object_id` set beforehand. """ if (isinstance(data, TrackedObject) and len(data) == 1): self._add_tobj(data) elif isinstance(data, Instance): self._add_instance(data) else: raise ValueError(f"Data of type {type(data)} " f"with len of {len(data)}is not supported.") dui = DataUpdateInfo(added=data) self.data_updated.emit( SignalPacket(sender=self.__class__.__name__, data=dui) ) return self
def run(self): while self.run_thread: # print("run_thread", self.idx) while self._play: # Keeping with our index keeping ############################## self.update_idx() # Handling videos flow ######################################## if self.prev_idx == self.idx: # We at the end of video self.stop() continue elif self.prev_idx == self.idx - 1: frame = self.next_frame() else: # In the case of jumping buffer or going backward frame = self.get_frame(self.idx) # TODO: Can import this if not isinstance(frame, np.ndarray): raise Exception else: self.frame = frame # for session in self.session: session() # fi = self.dh.from_frame(self.idx, to="frameinfo") # fi.frame = self.frame rr = RunResults(self.idx, "dummy") self.curr_frame.emit( SignalPacket(sender="Buffer", data=(frame.copy(), self.idx))) time.sleep(1 / self.fps) # fps time.sleep(0.1)
def _right_clicked(self): self.right_clicked.emit( SignalPacket(sender=self.__class__.__name__, data=(self.track_id, self.instance_id)))
def _left_clicked(self): self.left_clicked.emit( SignalPacket(sender=self.__class__.__name__, data=self.frame_id))
def _request_instance_sl(self, packet: SignalPacket): self.req_instance.emit( SignalPacket(sender=[*packet.sender, self.__class__.__name__], data=packet.data))
def request_frames(self): self.req_frames.emit( SignalPacket(sender=[self.__class__.__name__], data=self.frame_ids))