Source code for kalmus.barcodes.BarcodeGenerator

""" Barcode Generator Class"""

import numpy as np
import json

from kalmus.barcodes.Barcode import ColorBarcode, BrightnessBarcode

# Available metrics for computing the color of a frame
color_metrics = ["Average", "Median", "Mode", "Top-dominant", "Weighted-dominant",
                 "Brightest", "Bright"]

# Available types of sampling frame (which part of frame is region of interest)
frame_types = ["Whole_frame", "High_contrast_region", "Low_contrast_region", "Foreground", "Background"]

# Available types of barcode
barcode_types = ["Color", "Brightness"]


[docs]def build_barcode_from_json(path_to_json, barcode_type="Color"): """ Helper function that build a barcode object from the attributes stored in a json file :param path_to_json: Path to the json file :type path_to_json: str :param barcode_type: Type of the barcode that stored in the json file :type barcode_type: str :return: The barcode built from the json file at given path :rtype: class:`kalmus.barcodes.Barcode.ColorBarcode` or class:`kalmus.barcodes.Barcode.BrightnessBarcode` """ assert barcode_type in barcode_types, "Invalid barcode type. The available types of " \ "the barcode are {:s}".format(str(barcode_types)) with open(path_to_json, "r") as infile: object_dict = json.load(infile) infile.close() # Make sure the barcode_type is correctly capitalized barcode_type = barcode_type.capitalize() if barcode_type == "Color": barcode = ColorBarcode(color_metric=object_dict["color_metric"], frame_type=object_dict["frame_type"], sampled_frame_rate=object_dict["sampled_frame_rate"], skip_over=object_dict["skip_over"], total_frames=int(object_dict["total_frames"]), barcode_type=barcode_type) barcode.colors = np.array(object_dict["colors"]).astype("uint8") elif barcode_type == "Brightness": barcode = BrightnessBarcode(color_metric=object_dict["color_metric"], frame_type=object_dict["frame_type"], sampled_frame_rate=object_dict["sampled_frame_rate"], skip_over=object_dict["skip_over"], total_frames=int(object_dict["total_frames"]), barcode_type=barcode_type) barcode.brightness = np.array(object_dict["brightness"]).astype("uint8") barcode.set_letterbox_bound(object_dict["low_bound_ver"], object_dict["high_bound_ver"], object_dict["low_bound_hor"], object_dict["high_bound_hor"]) if ("meta_data" in object_dict.keys()) and (object_dict["meta_data"] is not None): barcode.meta_data = object_dict["meta_data"] barcode.barcode = np.array(object_dict["barcode"]) barcode.video = None if ("fps" in object_dict.keys()) and (object_dict["fps"] is not None): barcode.fps = float(object_dict["fps"]) else: barcode.fps = 30 barcode.film_length_in_frames = int(object_dict["film_length_in_frames"]) if "save_frames_in_generation" in object_dict.keys(): if object_dict["save_frames_in_generation"]: barcode.save_frames_in_generation = object_dict["save_frames_in_generation"] barcode.saved_frames = np.array(object_dict["saved_frames"]) return barcode
[docs]class BarcodeGenerator(): """ Barcode Generator Class :param frame_type: The type of the frame sampling :type frame_type: str :param color_metric: The metric of computing the frame color :type color_metric: str :param barcode_type: The type of the generated barcode :type barcode_type: str :param sampled_frame_rate: The frame sample rate \ (one frame will be sampled from every sampled_frame_rate frames) :type sampled_frame_rate: int :param skip_over: How many frames to skip with at the beginning of the input video :type skip_over: int :param total_frames: Total number of frames that will be computed (included in the barcode/sampled frames) :type total_frames: int """ def __init__(self, frame_type="Whole_frame", color_metric="Average", barcode_type="Color", sampled_frame_rate=1, skip_over=0, total_frames=10): """ Initialize the parameters for the barcode generator """ assert frame_type in frame_types, "Invalid frame acquisition method. Five types of frame acquisition" \ " methods are available including {:s}".format(str(frame_types)) assert color_metric in color_metrics, "Invalid color metric. Seven color metrics are available " \ "including {:s}".format(str(color_metrics)) assert barcode_type in barcode_types, "Invalid barcode type. Two types of barcode are available " \ "including {:s}".format(str(barcode_types)) assert not (color_metric == "Bright" and frame_type in frame_types[1:]), \ "Color metric Bright can not be used when the frame acquisition " \ "methods are {:s}".format(str(frame_types[1:])) self.frame_type = frame_type self.color_metric = color_metric self.barcode_type = barcode_type self.sampled_frame_rate = sampled_frame_rate self.skip_over = skip_over self.total_frames = total_frames self.barcode = None
[docs] def instantiate_barcode_object(self): """ Instantiate the barcode object using the given generation parameters """ if self.barcode_type == "Color": self.barcode = ColorBarcode(self.color_metric, self.frame_type, self.sampled_frame_rate, self.skip_over, self.total_frames, barcode_type="Color") elif self.barcode_type == "Brightness": self.barcode = BrightnessBarcode(self.color_metric, self.frame_type, self.sampled_frame_rate, self.skip_over, self.total_frames, barcode_type="Brightness")
[docs] def generate_barcode(self, video_file_path, user_defined_letterbox=False, low_ver=-1, high_ver=-1, left_hor=-1, right_hor=-1, num_thread=None, save_frames=False, rescale_frames_factor=-1, save_frames_rate=4): """ Generate the barcode :param video_file_path: The path to the video file :type video_file_path: str :param user_defined_letterbox: Whether use the user defined the letterbox, or use the \ automatically found letterbox :type user_defined_letterbox: bool :param low_ver: The lower vertical letterbox given by user :type low_ver: int :param high_ver: The higher vertical letterbox given by user :type high_ver: int :param left_hor: The left horizontal letterbox given by user :type left_hor: int :param right_hor: The right horizontal letterbox given by user :type right_hor: int :param num_thread: Number of thread for computation. None == Single thread. num_thread > 1: multi-thread :type num_thread: int :param save_frames: Whether to save the frames during the barcode generation :type save_frames: bool :param save_frames_rate: The period of seconds of one frame being saved. In other words, save 1 frame every \ save_frame_rate seconds in the barcode generation :type save_frames_rate: float :param rescale_frames_factor: factor to rescale the input frames during the generation :type rescale_frames_factor: float """ self.instantiate_barcode_object() if user_defined_letterbox: self.barcode.set_letterbox_bound(up_vertical_bound=high_ver, down_vertical_bound=low_ver, left_horizontal_bound=left_hor, right_horizontal_bound=right_hor) if save_frames and save_frames_rate > 0: self.barcode.enable_save_frames(sampled_rate=save_frames_rate) if rescale_frames_factor > 0: self.barcode.enable_rescale_frames_in_generation(rescale_frames_factor) if self.barcode_type == "Color": if num_thread is not None: self.barcode.multi_thread_collect_colors(video_file_path, num_thread) else: self.barcode.collect_colors(video_file_path) elif self.barcode_type == "Brightness": if num_thread is not None: self.barcode.multi_thread_collect_brightness(video_file_path, num_thread) else: self.barcode.collect_brightness(video_file_path)
[docs] def generate_barcode_from_json(self, json_file_path, barcode_type=None): """ Generate the barcode from a json file, which contain a dictionary representation of barcode object :param json_file_path: the path to the json file :type json_file_path: str :param barcode_type: the type of the barcode saved in the json file :type barcode_type: str """ if barcode_type is None: barcode_type = self.barcode_type self.barcode = build_barcode_from_json(json_file_path, barcode_type=barcode_type)
[docs] def get_barcode(self): """ return the barcode object stored in the Barcode generator :return: The generated barcode :rtype: class:`kalmus.barcodes.Barcode.ColorBarcode` or class:`kalmus.barcodes.Barcode.BrightnessBarcode` """ assert self.barcode is not None, "There is not a generated barcode" return self.barcode