def offline_detection( source_path, all_timestamps, frame_index_range, calculated_frame_indices, shared_memory, ): batch_size = 30 frame_start, frame_end = frame_index_range frame_indices = sorted( set(range(frame_start, frame_end + 1)) - calculated_frame_indices) if not frame_indices: return frame_count = frame_end - frame_start + 1 shared_memory.progress = (frame_indices[0] - frame_start + 1) / frame_count yield None src = video_capture.File_Source(SimpleNamespace(), source_path, fill_gaps=False, timing=None) timestamps_no_gaps = src.timestamps uncalculated_timestamps = all_timestamps[frame_indices] seek_poses = np.searchsorted(timestamps_no_gaps, uncalculated_timestamps) queue = [] for frame_index, timestamp, target_frame_idx in zip( frame_indices, uncalculated_timestamps, seek_poses): detections = [] if timestamp in timestamps_no_gaps: if target_frame_idx != src.target_frame_idx: src.seek_to_frame( target_frame_idx) # only seek frame if necessary frame = src.get_frame() detections = _detect(frame) serialized_dicts = [fm.Serialized_Dict(d) for d in detections] queue.append((timestamp, serialized_dicts, frame_index)) if len(queue) >= batch_size: shared_memory.progress = (frame_index - frame_start + 1) / frame_count data = queue[:batch_size] del queue[:batch_size] yield data yield queue
def offline_detection( source_path, timestamps, frame_index_range, frame_index_to_num_markers, shared_memory, ): batch_size = 30 frame_start, frame_end = frame_index_range frame_indices = sorted( set(range(frame_start, frame_end + 1)) - set(frame_index_to_num_markers.keys())) if not frame_indices: return frame_count = frame_end - frame_start + 1 shared_memory.progress = (frame_indices[0] - frame_start + 1) / frame_count yield None src = video_capture.File_Source(SimpleNamespace(), source_path, timing=None) queue = [] for frame_index in frame_indices: shared_memory.progress = (frame_index - frame_start + 1) / frame_count timestamp = timestamps[frame_index] src.seek_to_frame(frame_index) frame = src.get_frame() detections = _detect(frame) if detections: serialized_dicts = [ fm.Serialized_Dict(detection) for detection in detections ] queue.append( (timestamp, serialized_dicts, frame_index, len(detections))) else: queue.append((timestamp, [fm.Serialized_Dict({})], frame_index, 0)) if len(queue) >= batch_size: data = queue[:batch_size] del queue[:batch_size] yield data yield queue
def video_processing_generator(video_file_path, callable, seek_idx, visited_list): import os import logging logger = logging.getLogger(__name__ + " with pid: " + str(os.getpid())) logger.debug("Started cacher process for Marker Detector") import video_capture cap = video_capture.File_Source( types.SimpleNamespace(), source_path=video_file_path, fill_gaps=True, timing=None, ) # Ensure that indiced are not generated beyond video frame count frame_count = cap.get_frame_count() visited_list = visited_list[:frame_count] visited_list = [x is not None for x in visited_list] def next_unvisited_idx(frame_idx): """ Starting from the given index, find the next frame that has not been processed yet. If no future frames need processing, check from the start. Args: frame_idx: Index to start search from. Returns: Next index that requires processing. """ try: visited = visited_list[frame_idx] except IndexError: visited = True # trigger search from the start if not visited: next_unvisited = frame_idx else: # find next unvisited site in the future try: next_unvisited = visited_list.index(False, frame_idx) except ValueError: # any thing in the past? try: next_unvisited = visited_list.index(False, 0, frame_idx) except ValueError: # no unvisited sites left. Done! logger.debug("Caching completed.") next_unvisited = None return next_unvisited def handle_frame(frame_idx): if frame_idx != cap.get_frame_index() + 1: # we need to seek: logger.debug("Seeking to Frame {}".format(frame_idx)) try: cap.seek_to_frame(frame_idx) except video_capture.FileSeekError: logger.warning("Could not evaluate frame: {}.".format(frame_idx)) visited_list[frame_idx] = True # this frame is now visited. return [] try: frame = cap.get_frame() except video_capture.EndofVideoError: logger.warning("Could not evaluate frame: {}.".format(frame_idx)) visited_list[frame_idx] = True return [] return callable(frame) while True: last_frame_idx = cap.get_frame_index() if seek_idx.value != -1: assert seek_idx.value < len( visited_list ), "The requested seek index is outside of the predefined cache range!" last_frame_idx = seek_idx.value seek_idx.value = -1 logger.debug( "User required seek. Marker caching at Frame: {}".format(last_frame_idx) ) next_frame_idx = next_unvisited_idx(last_frame_idx) if next_frame_idx is None: break else: res = handle_frame(next_frame_idx) visited_list[next_frame_idx] = True yield next_frame_idx, res