Exemple #1
0
def writer(
    in_q: Queue,
    progress_queue: Queue,
    filename: str,
    fps: float,
):
    """Write annotated images to video.

    Image size is determined by the first image received in queue.

    Args:
        in_q: Queue with annotated images as (images, h, w, channels) ndarray
        progress_queue: Queue to send progress as
            (total frames written: int, elapsed time: float).
            Send (-1, elapsed time) when done.
        filename: full path to output video
        fps: frames per second for output video

    Returns:
        None.
    """

    cv2.setNumThreads(usable_cpu_count())

    writer_object = None
    total_elapsed = 0
    total_frames_written = 0
    start_time = clock()
    i = 0
    while True:
        data = in_q.get()

        if data is _sentinel:
            # no more data to be received so stop
            in_q.put(_sentinel)
            break

        if writer_object is None and data:
            h, w = data[0].shape[:2]
            writer_object = VideoWriter.safe_builder(filename,
                                                     height=h,
                                                     width=w,
                                                     fps=fps)

        t0 = clock()
        for img in data:
            writer_object.add_frame(img, bgr=True)

        elapsed = clock() - t0
        fps = len(data) / elapsed
        logger.debug(f"writing chunk {i} in {elapsed} s = {fps} fps")
        i += 1

        total_frames_written += len(data)
        total_elapsed = clock() - start_time
        progress_queue.put((total_frames_written, total_elapsed))

    writer_object.close()
    # send (-1, time) to signal done
    progress_queue.put((-1, total_elapsed))
Exemple #2
0
    def marker(self):
        cv2.setNumThreads(usable_cpu_count())

        chunk_i = 0
        while True:
            data = self.in_q.get()

            if data is _sentinel:
                # no more data to be received so stop
                self.in_q.put(_sentinel)
                break

            frames_idx_chunk, video_frame_images = data

            t0 = clock()

            imgs = self._mark_images(
                frame_indices=frames_idx_chunk,
                frame_images=video_frame_images,
            )

            elapsed = clock() - t0
            fps = len(imgs) / elapsed
            logger.debug(f"drawing chunk {chunk_i} in {elapsed} s = {fps} fps")
            chunk_i += 1
            self.out_q.put(imgs)

        # send _sentinal object into queue to signal that we're done
        self.out_q.put(_sentinel)
Exemple #3
0
def reader(out_q: Queue, video: Video, frames: List[int], scale: float = 1.0):
    """Read frame images from video and send them into queue.

    Args:
        out_q: Queue to send (list of frame indexes, ndarray of frame images)
            for chunks of video.
        video: The `Video` object to read.
        frames: Full list frame indexes we want to read.
        scale: Output scale for frame images.

    Returns:
        None.
    """

    cv2.setNumThreads(usable_cpu_count())

    total_count = len(frames)
    chunk_size = 64
    chunk_count = math.ceil(total_count / chunk_size)

    logger.info(f"Chunks: {chunk_count}, chunk size: {chunk_size}")

    i = 0
    for chunk_i in range(chunk_count):

        # Read the next chunk of frames
        frame_start = chunk_size * chunk_i
        frame_end = min(frame_start + chunk_size, total_count)
        frames_idx_chunk = frames[frame_start:frame_end]

        t0 = clock()

        # Safely load frames from video, skipping frames we can't load
        loaded_chunk_idxs, video_frame_images = video.get_frames_safely(
            frames_idx_chunk)

        if not loaded_chunk_idxs:
            print(f"No frames could be loaded from chunk {chunk_i}")
            i += 1
            continue

        if scale != 1.0:
            video_frame_images = resize_images(video_frame_images, scale)

        elapsed = clock() - t0
        fps = len(loaded_chunk_idxs) / elapsed
        logger.debug(f"reading chunk {i} in {elapsed} s = {fps} fps")
        i += 1

        out_q.put((loaded_chunk_idxs, video_frame_images))

    # send _sentinal object into queue to signal that we're done
    out_q.put(_sentinel)
Exemple #4
0
def marker(in_q: Queue, out_q: Queue, labels: Labels, video_idx: int,
           scale: float):
    """Annotate frame images (draw instances).

    Args:
        in_q: Queue with (list of frame indexes, ndarray of frame images).
        out_q: Queue to send annotated images as
            (images, h, w, channels) ndarray.
        labels: the `Labels` object from which to get data for annotating.
        video_idx: index of `Video` in `labels.videos` list.

    Returns:
        None.
    """

    cv2.setNumThreads(usable_cpu_count())

    chunk_i = 0
    while True:
        data = in_q.get()

        if data is _sentinel:
            # no more data to be received so stop
            in_q.put(_sentinel)
            break

        frames_idx_chunk, video_frame_images = data

        t0 = clock()

        imgs = mark_images(
            frame_indices=frames_idx_chunk,
            frame_images=video_frame_images,
            video_idx=video_idx,
            labels=labels,
            scale=scale,
        )

        elapsed = clock() - t0
        fps = len(imgs) / elapsed
        logger.debug(f"drawing chunk {chunk_i} in {elapsed} s = {fps} fps")
        chunk_i += 1
        out_q.put(imgs)

    # send _sentinal object into queue to signal that we're done
    out_q.put(_sentinel)