cvvideoplayer

moduler multi purpose video player for python


License
MIT
Install
pip install cvvideoplayer==0.1.4

Documentation

Introduction

CV video player is a Python-based customizable video player that helps computer vision practitioners to develop, analyze, and debug their video-related algorithms and models.

The video player is interactive, operating only with keyboard presses (no UI buttons). The user can register shortcuts using the VideoPlayer class's API.

See it in action

Running frame by frame

frame_by_frame

Play/Pause and control play speed and direction

playpause

Draw bounding boxes and adjust labels

bboxes

Installation

pip install cvvideoplayer

Usage

Design overview

The player receives an image from the FrameReader, the frame is then passed to a list of frame editors which alter it in any way desirable and return the frame. The frame editors also specify whether to perform the edit after the frame has been resized to fit the screen or before.

FrameReader class

Implements the following protocol:

class FrameReader(abc.ABC):
    @abc.abstractmethod
    def get_frame(self, frame_num: int) -> Optional[np.ndarray]:
        pass

    @abc.abstractmethod
    def __len__(self) -> int:
        pass

A ready-to-use LocalFrameReader is already implemented and can be used to read any local video file or folder containing the frames as images (as long as there is a number in the name of the image files indicating their order).

BaseFrameEditor class

You can add any number of frame editores for the player to apply using the VideoPlayer method add_frame_editor. A frame editor is an instance of a class that inherit BaseFrameEditor and implements the following abstract methods:

class BaseFrameEditor(ABC):
    @property
    @abstractmethod
    def edit_after_resize(self) -> bool:
        """
        Returns a boolean indicating whether the edit should happen before the frame is resized to fit the frame or
        after. True for after...
        """
        pass

    @abstractmethod
    def _edit_frame(self, frame: np.ndarray, frame_num: int) -> np.ndarray:
        """
        Here is where the editing happens. The function receives a frame and frame number and should return the frame
        after it has been altered in any way desirable by the user

        Args:
            frame (): the input frame
            frame_num ():

        Returns: the edited frame
        """
        pass
KeyFunction dataclass

A KeyFunction defines a mapping between a key and a function with an added description of the function's purpose. You can add a new KeyFunction in two ways:

  • Using the video player's method register_key_function
  • Using a FrameEditors property key_functions_to_register which returns a list of KeyFunctions that will be registered once the FrameEditor is added to the player

default key functions:

These are used by the player and cannot be overwritten:

  • "space bar": Play/Pause video
  • "right": Next frame
  • "left": Previous frame
  • "ctrl+right": 10 frames forward
  • "ctrl+left": 10 frames back
  • "ctrl+shift+right": 50 frames forward
  • "ctrl+shift+left": 50 frames back
  • "+": Double play speed
  • "-": half play speed
  • "ctrl++": Increase frame size
  • "ctrl+-": Decrease frame size
Recorder class

The Recorder class can be used to record whatever is being played in the video player. By default, the video will be saved in an "outputs" folder which will be automatically created in the CWD.

To use the Recorder:

from cvvideoplayer import VideoPlayer, Recorder
video_player = VideoPlayer(
    recorder=Recorder(),
    **other_video_player_kwargs
)

Quick Start

from cvvideoplayer import LocalFrameReader, Recorder, VideoPlayer

VIDEO_OR_FRAME_FOLDER_PATH = <add local path here>

def run_player():
    video_player = VideoPlayer(
        video_name="example_video",
        frame_reader=LocalFrameReader(source_path=VIDEO_OR_FRAME_FOLDER_PATH),
        recorder=Recorder(),
        add_basic_frame_editors=True,
    )

    with video_player:
        video_player.run()


if __name__ == "__main__":
    run_player()

In this example, we initiate a very basic video player that will play "example_video.mp4" with added basic frame editors:

  • Frame number printer (disable/enable with ctrl+f): Prints the current frame number and original frame resolution in the top left corner
  • Histogram Equalizer (disable/enable with ctrl+h): Preforms histogram equalization on the image
  • Frame Normalizer: Allows the user to print the current frame's intensities histogram and also set a dynamic range for the image (see printed keymap at runtime for the used keyboard shortcuts).

Check out the run_video_player.py which also uses the DetectionsCsvPlotter to plot precalculated detection