Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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