def create_sequences_not_yet_existing(self, video_file_id, label_file_id, number): """ We also create self.sequence_number_to_id because each instance needs a sequence_id to work as expected in downstream systems. Yet we cannot guarnatee that sequence_id existed prior as it may have just been created Sequences only apply relevant for videos (not images) In current context we enforce uniqinuess per label but trying to move away from that It's critical we get the sequence_id on the instance otherwise the preview image and various keyframe features will fail. """ # Existing sequence = Sequence.get_from_video_label_number( session=self.session, video_file_id=video_file_id, label_file_id=label_file_id, number=number) if sequence: self.sequence_number_to_id[(label_file_id, number)] = sequence.id return # Caution note it needs file object not just int here label_file = File.get_by_id_and_project(self.session, self.project.id, label_file_id) # For now just hard return if label_file is None: self.input.update_log['error'][str(label_file_id)] = "Label File ID: " + str(label_file_id) + \ "Does not exist in the project. Found at sequence Number: " + str(number) return sequence = Sequence.new(number=number, video_file_id=video_file_id, label_file=label_file) self.session.add(sequence) self.session.flush() # For ID self.sequence_number_to_id[(label_file_id, number)] = sequence.id print("Created sequence")
def create_sequence_preview_core(session, log, project, sequence_id): result = {'created': False} sequence = Sequence.get_by_id(session, sequence_id) if sequence.video_file.project_id != project.id: log['error']['project_id'] = 'Sequence ID project mismatch' return result, log # Build preview instance_preview = sequence.build_instance_preview_dict(session=session) if instance_preview: result['created'] = True result['instance_preview'] = instance_preview return result, log
def create_sequence(sequence_data, session): sequence = Sequence( label_file_id=sequence_data.get('label_file_id'), has_changes=sequence_data.get('has_changes'), single_frame=sequence_data.get('single_frame'), keyframe_list=sequence_data.get('keyframe_list'), video_file_id=sequence_data.get('video_file_id'), number=sequence_data.get('number'), instance_preview_cache=sequence_data.get('instance_preview_cache'), cache_expiry=sequence_data.get('cache_expiry'), archived=sequence_data.get('archived'), ) session.add(sequence) regular_methods.commit_with_rollback(session) return sequence
def add_sequence_map_to_input(self, source_video_parent_file, destination_video_parent_file_id): sequence_list = Sequence.list( session=self.session, video_file_id=source_video_parent_file.id) # This will map the new sequences old_id => new_id old_new_sequence_map = {} for sequence in sequence_list: sequence_copy = sequence.clone_sequence_with_no_instances( self.session, destination_video_parent_file_id= destination_video_parent_file_id) old_new_sequence_map[sequence.id] = sequence_copy.id # Add sequence map to parent input self.input.sequence_map = old_new_sequence_map return
def update_sequence_shared(session, project, file_id: int, sequence_id: int, mode: str, payload): """ CAUTION if there are things that depend / stored on both sequence and instance will also need to updated here over time ie if we add something else that is unique to each sequence but stored on instance (like the "Number"). Assumes sequence is valid if file id matches. Assumes label file is valid if it matches project. verifying label file alternatively look at implmentation in annotation.py ie get_allowed_label_file_ids() This is pretty "basic" right now... maybe other stuff to think about in terms of what to update... The number could conflict... Need to update number to highest could also just set it to big number... """ if file_id is None or sequence_id is None or payload is None: return "a required argument is none", 400, { 'ContentType': 'application/json' } log = regular_log.default() sequence = session.query(Sequence).filter( Sequence.video_file_id == file_id, Sequence.id == sequence_id).first() if sequence is None: return jsonify("Not found"), 400 if mode == "update_label": if sequence.label_file_id == payload.get('id'): log['error'][ 'label_file_id'] = "Same label selected, nothing to change." return jsonify(log=log), 400 label_file = File.get_by_id_and_project(project_id=project.id, session=session, file_id=payload.get('id')) if label_file is None: return jsonify("Not found"), 400 highest_sequence_in_new_context = Sequence.get_by_highest_number( session=session, video_file_id=file_id, label_file_id=label_file.id) if highest_sequence_in_new_context: new_sequence_number: int = highest_sequence_in_new_context.number + 1 else: new_sequence_number: int = 1 # dict, order may disaply different on front end. log['info']['moved_sequence_to_label_file'] = "Updated to: '" + \ label_file.label.name + "'. Click the label to see it." log['info']['new_sequence_number'] = "Updated sequence number to: " + \ str(new_sequence_number) sequence.number = new_sequence_number sequence.label_file = label_file session.add(sequence) instances_updated_count = 0 for instance in sequence.instance_list: if mode == "update_label": instance.label_file_id = label_file.id instance.number = new_sequence_number session.add(instance) instances_updated_count += 1 # TODO would prefer to just get frames relevant to sequence... file_list = WorkingDirFileLink.image_file_list_from_video( session=session, video_parent_file_id=file_id) # Future, something like -> sequence.frame_list(session) for file in file_list: file.set_cache_key_dirty('instance_list') session.add(file) log['info']['instances_updated'] = "Updated " + str(instances_updated_count) + \ " Instance(s)." log['success'] = True return jsonify(log=log), 200