""" GenerateBarcodeWindow Class """
import cv2
import tkinter
import tkinter.filedialog
from tkinter.messagebox import showerror, showwarning, showinfo
import copy
import os
import threading
from kalmus.tkinter_windows.meta_info_windows.SpecifyMetaDataWindow import SpecifyMetaDataWindow
from kalmus.tkinter_windows.gui_utils import resource_path
[docs]class GenerateBarcodeWindow():
"""
GenerateBarcodeWindow Class
GUI window for user to generate the barcode from a video file
"""
def __init__(self, barcode_generator, barcode_stack):
"""
Initialize
:param barcode_generator: The barcode generator
:param barcode_stack: The dictionary that stores all the barcode on the memory
"""
self.barcode_generator = barcode_generator
self.barcode_stack = barcode_stack
# Initialize the window
self.window = tkinter.Tk()
self.window.wm_title("Barcode Generator")
self.window.iconbitmap(resource_path("kalmus_icon.ico"))
# A temporary meta data dictionary that will hold the meta information given by the user
self.meta_data_dict = {}
# video object capture by cv2
self.video = None
# Label prompt for the generated barcode's barcode type
barcode_type_label = tkinter.Label(self.window, text="Barcode Type: ")
barcode_type_label.grid(row=0, column=0)
# Label prompt for the frame sampling type
frame_type_label = tkinter.Label(self.window, text="Frame Type: ")
frame_type_label.grid(row=1, column=0)
# Label prompt for the color/brightness metric
color_metric_label = tkinter.Label(self.window, text="Color Metric: ")
color_metric_label.grid(row=2, column=0)
# Variable that stores the user's choice of generated barcode type
self.barcode_type_var = tkinter.StringVar(self.window)
self.barcode_type_var.set("Color")
# Dropdown menu for the barcode type selection
dropdown_bar_type = tkinter.OptionMenu(self.window, self.barcode_type_var, "Color", "Brightness")
dropdown_bar_type.grid(row=0, column=1)
# Variable that stores the user's choice of frame sampling type
self.frame_type_var = tkinter.StringVar(self.window)
self.frame_type_var.set("Whole_frame")
# Dropdown menu for the frame sampling type selection
dropdown_frame_type = tkinter.OptionMenu(self.window, self.frame_type_var, "Whole_frame", "Low_contrast_region",
"High_contrast_region", "Foreground", "Background")
dropdown_frame_type.grid(row=1, column=1)
# Variable that stores the user's choice of color metric
self.color_metric_var = tkinter.StringVar(self.window)
self.color_metric_var.set("Average")
# Dropdown menu for the color metric selection
dropdown_color_metric = tkinter.OptionMenu(self.window, self.color_metric_var, "Average", "Median", "Mode",
"Top-dominant", "Weighted-dominant", "Bright", "Brightest")
dropdown_color_metric.grid(row=2, column=1)
# Label prompt for the skip over specification
self.skip_over_label = tkinter.Label(self.window, text="Start at (frames): ")
self.skip_over_label.grid(row=0, column=2)
# Label prompt for the sample rate specification
self.sampled_rate_label = tkinter.Label(self.window, text="Sample every (frames): ")
self.sampled_rate_label.grid(row=1, column=2)
# Label prompt for the total frame included specification
self.total_frames_label = tkinter.Label(self.window, text="Total frames: ")
self.total_frames_label.grid(row=2, column=2)
# Acquisition unit specification (in frames or in time)
self.acquisition_label = tkinter.Label(self.window, text="Acquistion unit")
self.acquisition_label.grid(row=0, column=5)
# Variable that stores the user's choice of acquisition unit
self.acquisition_option = tkinter.StringVar(self.window)
self.acquisition_option.set("Frame")
# Radio button for the Acquisition unit (Frame/Time) selection
self.radio_frame = tkinter.Radiobutton(self.window, text="Frame", variable=self.acquisition_option,
value="Frame", anchor='w',
command=self.frame_unit)
self.radio_frame.grid(row=1, column=5, sticky=tkinter.W)
self.radio_frame.select()
self.radio_time = tkinter.Radiobutton(self.window, text="Time", variable=self.acquisition_option,
value="Time", anchor='w',
command=self.time_unit)
self.radio_time.grid(row=2, column=5, sticky=tkinter.W)
# Text entry for the skip over specification
self.skip_over_entry = tkinter.Entry(self.window, textvariable="0", width=12)
self.skip_over_entry.grid(row=0, column=3, columnspan=2)
# Text entry for the sampling rate specification
self.sampled_rate_entry = tkinter.Entry(self.window, textvariable="1", width=12)
self.sampled_rate_entry.grid(row=1, column=3, columnspan=2)
# Text entry for the total frames specification
self.total_frames_entry = tkinter.Entry(self.window, textvariable="1000", width=12)
self.total_frames_entry.grid(row=2, column=3, columnspan=2)
# Label prompt for the video file name input
video_filename_label = tkinter.Label(self.window, text="Media file path: ")
video_filename_label.grid(row=3, column=0, columnspan=1)
# Text entry for the video file name specification
self.video_filename_entry = tkinter.Entry(self.window, textvariable="", width=55)
self.video_filename_entry.grid(row=3, column=1, columnspan=3)
# Button to browse the folder
self.browse_folder_button = tkinter.Button(self.window, text='Browse', command=self.browse_folder)
self.browse_folder_button.grid(row=3, column=4)
# Variable that stores 0 for not saving JSON file 1 for saving generated barcode to JSON
self.var_save_json = tkinter.IntVar(self.window)
# Checkbox for the user to choose whether use the multi-thread or not for barcode generation
self.checkbox_save_json = tkinter.Checkbutton(self.window, text="Save Output:",
variable=self.var_save_json,
onvalue=1, offvalue=0, command=self.update_json_filename)
self.checkbox_save_json.grid(row=4, column=0)
# Text entry for the output JSON file name specification
self.json_filename_entry = tkinter.Entry(self.window, textvariable="", width=55)
self.json_filename_entry.grid(row=4, column=1, columnspan=3)
self.json_filename_entry.config(state="disabled")
# Variable that stores the letter box option (automatic/user defined)
self.letterbox_option = tkinter.StringVar(self.window)
self.letterbox_option.set("Auto") # initialize
# Label prompt for the letter box remove option
letterbox_label = tkinter.Label(self.window, text="Remove Letterbox: ")
letterbox_label.grid(row=5, column=0, columnspan=1)
# Radio button for the letter box remove option
self.radio_auto = tkinter.Radiobutton(self.window, text="Auto", variable=self.letterbox_option,
value="Auto", anchor='w',
command=self.disable_setup)
self.radio_auto.grid(row=6, column=0, sticky=tkinter.W)
self.radio_auto.select()
self.radio_manual = tkinter.Radiobutton(self.window, text="Manual", variable=self.letterbox_option,
value="Manual", anchor='w',
command=self.enable_setup)
self.radio_manual.grid(row=7, column=0, sticky=tkinter.W)
# User defined letter box label prompt
high_ver_label = tkinter.Label(self.window, text="Upper vertical: ")
high_ver_label.grid(row=6, column=1, columnspan=1)
low_ver_label = tkinter.Label(self.window, text="Lower vertical: ")
low_ver_label.grid(row=7, column=1, columnspan=1)
# User defined letter box text entry
self.high_ver_entry = tkinter.Entry(self.window, textvariable="-1", width=4, state="disabled")
self.high_ver_entry.grid(row=6, column=2, columnspan=1, sticky=tkinter.W)
self.low_ver_entry = tkinter.Entry(self.window, textvariable="-2", width=4, state="disabled")
self.low_ver_entry.grid(row=7, column=2, columnspan=1, sticky=tkinter.W)
left_hor_label = tkinter.Label(self.window, text="Left horizontal: ")
left_hor_label.grid(row=6, column=3, columnspan=1)
right_hor_label = tkinter.Label(self.window, text="right horizontal: ")
right_hor_label.grid(row=7, column=3, columnspan=1)
self.left_hor_entry = tkinter.Entry(self.window, textvariable="-3", width=4, state="disabled")
self.left_hor_entry.grid(row=6, column=4, columnspan=1)
self.right_hor_entry = tkinter.Entry(self.window, textvariable="-4", width=4, state="disabled")
self.right_hor_entry.grid(row=7, column=4, columnspan=1)
# Variable that stores 0 for not saving frames during the generation 1 for saving frames during the generation
self.var_saved_frame = tkinter.IntVar(self.window)
# Checkbox for the user to choose whether save the frames or not during barcode generation
self.checkbox_saved_frame = tkinter.Checkbutton(self.window, text="Save Frames ",
variable=self.var_saved_frame,
onvalue=1, offvalue=0, command=self.update_save_frame_entry)
self.checkbox_saved_frame.grid(row=8, column=0)
# Label prompt for saving frame
save_frame_label = tkinter.Label(master=self.window, text="Save every (secs):")
save_frame_label.grid(row=8, column=1, sticky=tkinter.E)
# Text entry for the saved frames rate specification
self.save_frame_entry = tkinter.Entry(self.window, textvariable="-8", width=4, state="normal")
self.save_frame_entry.grid(row=8, column=2, sticky=tkinter.W)
self.save_frame_entry.delete(0, tkinter.END)
self.save_frame_entry.insert(0, "4")
self.save_frame_entry.config(state="disabled")
# Variable that stores 0 for not saving frames during the generation 1 for rescaling frame
# during the generation
self.var_rescale_frame = tkinter.IntVar(self.window)
# Checkbox for the user to choose whether to rescale the frames or not during the barcode generation
self.checkbox_rescale_frame = tkinter.Checkbutton(self.window, text="Rescale Frames", width=12,
variable=self.var_rescale_frame,
onvalue=1, offvalue=0, command=self.update_rescale_entry)
self.checkbox_rescale_frame.grid(row=8, column=3, sticky=tkinter.E)
# Text entry for the rescale factor specification
self.rescale_factor_entry = tkinter.Entry(self.window, textvariable="-7", width=4, state="normal")
self.rescale_factor_entry.grid(row=8, column=4)
self.rescale_factor_entry.delete(0, tkinter.END)
self.rescale_factor_entry.insert(0, "0.5")
self.rescale_factor_entry.config(state="disabled")
# Variable that stores 0 for single thread generation 1 for multi-thread generation
self.var_multi_thread = tkinter.IntVar(self.window)
# Checkbox for the user to choose whether use the multi-thread or not for barcode generation
self.checkbox_multi_thread = tkinter.Checkbutton(self.window, text="Multi-Thread:",
variable=self.var_multi_thread,
onvalue=1, offvalue=0, command=self.update_thread_entry)
self.checkbox_multi_thread.grid(row=9, column=0)
# Text entry for the thread specification
self.thread_entry = tkinter.Entry(self.window, textvariable="-6", width=4, state="normal")
self.thread_entry.grid(row=9, column=1, sticky=tkinter.W)
self.thread_entry.delete(0, tkinter.END)
self.thread_entry.insert(0, "4")
self.thread_entry.config(state="disabled")
# Button to generate the barcode
self.generate_button = tkinter.Button(master=self.window, text="Generate Barcode",
command=self.generate_barcode_thread)
self.generate_button.grid(row=9, column=2, sticky=tkinter.W, rowspan=1, pady=5)
# Button to specify the meta data of the generated barcode
self.specify_data_button = tkinter.Button(master=self.window, text="Specify Meta Data",
command=self.specify_data)
self.specify_data_button.grid(row=9, column=3, sticky=tkinter.W, rowspan=1, pady=5)
self.use_default_setting_button = tkinter.Button(master=self.window, text="Default Setting",
command=self.fill_default_setting)
self.use_default_setting_button.grid(row=9, column=4, sticky=tkinter.E,
rowspan=1, columnspan=2, pady=5, padx=15)
self.window.protocol("WM_DELETE_WINDOW", self.quit)
# Start the window
self.window.mainloop()
[docs] def quit(self):
"""
Quit the main window
"""
self.window.quit()
self.window.destroy()
[docs] def specify_data(self):
"""
Instantiate the SpecifyMetaDataWindow
"""
SpecifyMetaDataWindow(self.meta_data_dict)
[docs] def update_json_filename(self):
if self.var_save_json.get() == 0:
self.checkbox_save_json["text"] = "Save Output:"
self.json_filename_entry.config(state="disabled")
elif self.var_save_json.get() == 1:
self.checkbox_save_json["text"] = "JSON file path:"
self.json_filename_entry.config(state="normal")
[docs] def fill_default_setting(self):
self.barcode_type_var.set("Color")
self.frame_type_var.set("Whole_frame")
self.color_metric_var.set("Average")
self.acquisition_option.set("Frame")
self.radio_frame.select()
self.radio_time.deselect()
self.radio_frame.invoke()
self.skip_over_entry.delete(0, tkinter.END)
self.skip_over_entry.insert(0, "start")
self.sampled_rate_entry.delete(0, tkinter.END)
self.sampled_rate_entry.insert(0, "2")
self.total_frames_entry.delete(0, tkinter.END)
self.total_frames_entry.insert(0, "end")
self.letterbox_option.set("Auto")
self.radio_auto.select()
self.radio_manual.deselect()
self.radio_auto.invoke()
self.checkbox_saved_frame.deselect()
self.checkbox_saved_frame.invoke()
self.save_frame_entry.delete(0, tkinter.END)
self.save_frame_entry.insert(0, "4")
self.checkbox_rescale_frame.select()
self.checkbox_rescale_frame.invoke()
self.checkbox_save_json.deselect()
self.checkbox_save_json.invoke()
if len(self.json_filename_entry.get()) <= 0:
default_json_save_path = "saved_{:s}_barcode_{:s}_{:s}.json"\
.format(self.barcode_type_var.get(), self.frame_type_var.get(), self.color_metric_var.get())
self.json_filename_entry.delete(0, tkinter.END)
self.json_filename_entry.insert(0, os.path.abspath(default_json_save_path))
[docs] def update_thread_entry(self):
"""
Enable or disable and change the label prompt when user check/uncheck the multi-thread checkbox
"""
if self.var_multi_thread.get() == 0:
self.checkbox_multi_thread["text"] = "Multi-Thread:"
self.thread_entry.config(state="disabled")
elif self.var_multi_thread.get() == 1:
self.checkbox_multi_thread["text"] = "# of Threads:"
self.thread_entry.config(state="normal")
[docs] def update_rescale_entry(self):
"""
Enable or disable and change the label prompt when user check/uncheck the rescale frames checkbox
"""
if self.var_rescale_frame.get() == 0:
self.checkbox_rescale_frame["text"] = "Rescale Frames"
self.rescale_factor_entry.config(state="disabled")
elif self.var_rescale_frame.get() == 1:
self.checkbox_rescale_frame["text"] = "By a factor of: "
self.rescale_factor_entry.config(state="normal")
[docs] def update_save_frame_entry(self):
"""
Enable or disable the text entry when user check/uncheck the save frames checkbox
"""
if self.var_saved_frame.get() == 0:
self.save_frame_entry.config(state="disabled")
elif self.var_saved_frame.get() == 1:
self.save_frame_entry.config(state="normal")
[docs] def time_unit(self):
"""
Change the acquisition unit to Time when user switch to the time radio button
"""
self.skip_over_label['text'] = "Start at (mins:secs): "
self.sampled_rate_label['text'] = "Sample every (secs): "
self.total_frames_label['text'] = "End at (mins:secs): "
[docs] def frame_unit(self):
"""
Change the acquisition unit to Frame when user switch to the frame radio button
"""
self.skip_over_label['text'] = "Start at (frames): "
self.sampled_rate_label['text'] = "Sample every (frames): "
self.total_frames_label['text'] = "Total frames: "
[docs] def browse_folder(self):
"""
Browse the folder
"""
# Get the file name from the user specification
filename = tkinter.filedialog.askopenfilename(initialdir="", title="Select Media file",
filetypes=(("mp4 files", "*.mp4"), ("avi files", "*.avi"),
("m4v files", "*.m4v"), ("All files", "*.*")))
# Update the file name to the text entry
self.video_filename_entry.delete(0, tkinter.END)
self.video_filename_entry.insert(0, filename)
[docs] def generate_barcode_thread(self):
"""
Generate the barcode in a another thread
to avoid the frozen tkinter window issue
:return:
"""
threading.Thread(target=self.generate_barcode).start()
[docs] def acquire_generation_param(self):
"""
Acquire the barcode generation parameters
"""
# Get barcode type, frame sampling type, and color/brightness metric
barcode_type = self.barcode_type_var.get()
frame_type = self.frame_type_var.get()
color_metric = self.color_metric_var.get()
# Get the acquisition unit
unit_type = self.acquisition_option.get()
# Get the file name/path of the input video
video_filename = str(self.video_filename_entry.get())
if not os.path.exists(video_filename):
showerror("Video File Not Exists", "Video file not found!\nPlease check the file path.")
raise FileNotFoundError()
# Get the correct acquisition parameters based on the acqusition unit
if unit_type == "Frame":
skip_over_str = self.skip_over_entry.get()
if len(skip_over_str) == 0 or skip_over_str.lower() == "start":
skip_over = 0
else:
skip_over = int(self.skip_over_entry.get())
total_frames_str = self.total_frames_entry.get()
if len(total_frames_str) == 0 or total_frames_str.lower() == "end":
total_frames = int(1e8)
else:
total_frames = int(self.total_frames_entry.get())
sampled_frame_rate_str = self.sampled_rate_entry.get()
if len(sampled_frame_rate_str) == 0:
showwarning("Sample Frame not Specified", "Sample frame rate is not given.\n"
"Default sample rate 1 frame every input frame is used.")
sampled_frame_rate = 1
else:
sampled_frame_rate = int(sampled_frame_rate_str)
elif unit_type == "Time":
self.video = cv2.VideoCapture(video_filename)
fps = self.video.get(cv2.CAP_PROP_FPS)
skip_over_str = str(self.skip_over_entry.get())
if len(skip_over_str) == 0 or skip_over_str.lower() == "start":
skip_over = 0
else:
split_pos = skip_over_str.find(":")
skip_over = int((int(skip_over_str[:split_pos]) * 60 + int(skip_over_str[split_pos + 1:])) * fps)
sampled_frame_rate_str = str(self.sampled_rate_entry.get())
if len(sampled_frame_rate_str) == 0:
showwarning("Sample Frame not Specified", "Sample frame rate is not given.\n"
"Default sample rate 1 frame every input frame is used.")
sampled_frame_rate = 1
else:
sampled_frame_rate = int(round(float(sampled_frame_rate_str) * fps))
total_frames_str = str(self.total_frames_entry.get())
if len(total_frames_str) == 0 or total_frames_str.lower() == "end":
total_frames = int(1e8)
else:
split_pos = total_frames_str.find(":")
total_frames = (int(total_frames_str[:split_pos]) * 60 + int(total_frames_str[split_pos + 1:])) * fps
total_frames -= skip_over
total_frames = int(total_frames)
total_frames //= sampled_frame_rate
# Make sure the sampled frame rate >= 1 and the skip over >= 0 and total frame >= 0
if sampled_frame_rate < 1:
showwarning("Frame Sample Rate too Small", "The frame sample rate is too small.\n"
"It has been adjusted to the Minimum valid sample rate,\n"
"Sample 1 frame every frame (==use all frames)")
sampled_frame_rate = 1
if skip_over < 0:
showwarning("Invalid Start time", "Invalid start time for the barcode generation.\n"
"Start frames/time has been set to 0/00:00 (== start of film)")
skip_over = 0
if total_frames < 0:
showwarning("Invalid Total Frames", "Invalid total frames\n"
"or Barcode starts after it ends.\n"
"Total frames has been adjusted to 0.")
total_frames = 0
return barcode_type, frame_type, color_metric, sampled_frame_rate, skip_over, total_frames, video_filename
[docs] def generate_barcode(self):
"""
Generate the barcode using the given parameters
"""
self.disable_generate_button()
try:
barcode_type, frame_type, color_metric, sampled_frame_rate, skip_over, total_frames, video_filename = \
self.acquire_generation_param()
except FileNotFoundError:
self.enable_generate_button()
return
except:
showerror("Acquisition Parameters", "An unknown Error occurred when reading\n"
"the acquisition parameters.\n\n"
"Please make sure all parameters are positive\n"
"Frames units must all be integers\n"
"In Time unit, mins:secs in Start and End at must be integers\n"
"Sample every (secs) can be decimals but not fraction.")
self.enable_generate_button()
return
# Update all the parameters to the barcode generator
self.barcode_generator.barcode_type = barcode_type
self.barcode_generator.frame_type = frame_type
self.barcode_generator.color_metric = color_metric
self.barcode_generator.sampled_frame_rate = sampled_frame_rate
self.barcode_generator.skip_over = skip_over
self.barcode_generator.total_frames = total_frames
if self.var_save_json.get() == 1:
json_filename = self.json_filename_entry.get()
if len(json_filename) == 0:
showwarning("Default Saved JSON Path is Used", "Path to the saved JSON file is not specified.\n"
"Default save path is used.\n"
"File will be saved in the current working directory.\n"
"It is recommended to specify the file path.")
json_filename = None
if json_filename and (not json_filename.endswith(".json")):
json_filename += ".json"
# Check if user choose the multi-thread or not
if self.var_multi_thread.get() == 0:
multi_thread = None
elif self.var_multi_thread.get() == 1:
# If user choose to use the multi-thread, then get the number of threads that will be used
try:
multi_thread = int(self.thread_entry.get())
if multi_thread < 1:
showwarning("Non Positive Thread Number", "Number of threads has been adjusted to 1.\n"
"Degenerated to single thread generation.")
multi_thread = 1
except:
showerror("Invalid Thread Number", "Invalid number of threads.\n"
"Number of threads must be an integer")
self.enable_generate_button()
return
# Check if user choose to save the frames or not
if self.var_saved_frame.get() == 1:
save_frames = True
try:
save_frames_rate = int(self.save_frame_entry.get())
except:
showerror("Invalid Save Frame Rate", "Invalid Save frame rate.\n"
"Save frame rate must be a positive Integer.")
self.enable_generate_button()
else:
save_frames_rate = -1
save_frames = False
# Check if user choose to rescale the frames or not
if self.var_rescale_frame.get() == 1:
try:
rescale_factor = float(self.rescale_factor_entry.get())
except:
showerror("Invalid Rescale Factor", "Invalid frame rescale factor.\n"
"Must be a positive number.\n"
"It can be a decimal number but not fractions")
self.enable_generate_button()
return
else:
rescale_factor = -1
# Check if user choose to define the letter box region manually
if self.letterbox_option.get() == "Manual":
try:
# Update the letter box parameters, if user choose Manual
high_ver = int(self.high_ver_entry.get())
low_ver = int(self.low_ver_entry.get())
left_hor = int(self.left_hor_entry.get())
right_hor = int(self.right_hor_entry.get())
# Start the generation
self.barcode_generator.generate_barcode(video_filename, user_defined_letterbox=True,
low_ver=low_ver, high_ver=high_ver,
left_hor=left_hor, right_hor=right_hor,
num_thread=multi_thread, save_frames=save_frames,
rescale_frames_factor=rescale_factor,
save_frames_rate=save_frames_rate)
except:
showwarning("Error Occurred in Barcode Generation", "An unknown Error occurred in the barcode "
"generation.\nPlease check the letterbox set up"
" and the other parameters' specification.")
self.enable_generate_button()
return
elif self.letterbox_option.get() == "Auto":
# try:
# If not, start the generation.
# The letter box will be automatically found during the generation process
self.barcode_generator.generate_barcode(video_filename, num_thread=multi_thread,
save_frames=save_frames,
rescale_frames_factor=rescale_factor,
save_frames_rate=save_frames_rate)
# except:
# showwarning("Error Occurred in Barcode Generation", "An unknown Error occurred in the barcode "
# "generation.\nPlease check the parameters' "
# "specification.")
# self.enable_generate_button()
# return
# Correct the total frames
total_frames = self.barcode_generator.get_barcode().total_frames
# Get the key of the barcode, which will be later stored in the memory stack (dictionary)
start_pos = video_filename.rfind("/") + 1
if start_pos < 0:
start_pos = 0
end_pos = video_filename.rfind(".")
videoname = video_filename[start_pos:end_pos] + "_" + barcode_type + "_" + frame_type + "_" + color_metric \
+ "_" + str(skip_over) + "_" + str(sampled_frame_rate) + "_" + str(total_frames)
# Get the barcode from the barcode generator
barcode = self.barcode_generator.get_barcode()
if self.var_save_json.get() == 1:
try:
barcode.save_as_json(json_filename)
if json_filename is None:
json_filename = "saved_{:s}_barcode_{:s}_{:s}.json" \
.format(barcode.barcode_type, barcode.frame_type, barcode.color_metric)
json_filename = os.path.abspath(json_filename)
json_saved_success_message = "\nand is saved as a JSON object at path: {:20s}" \
.format(json_filename)
except:
showwarning("Error Occurred in Saving Barcode", "An unknown Error occurred in saving barcode to "
"JSON object.\nPlease verify the file path and "
"make sure you have the permission to save file "
"at that directory.")
json_saved_success_message = ""
else:
json_saved_success_message = ""
# Clear the cv2 captured video object
barcode.video = None
# Update the user pre-defined meta data to the computed barcode
barcode.meta_data = copy.deepcopy(self.meta_data_dict)
# Add the generated barcode to the memory stack (dictionary)
self.barcode_stack[videoname] = copy.deepcopy(barcode)
# Enable the generate button for the next barcode generation request
self.enable_generate_button()
# Reset the meta data to the initial state
self.meta_data_dict = {}
# Show barcode generation success message
showinfo("Finished Successfully", "{:s} {:s} {:s} Barcode of the input video:\n"
"{:20s}\n"
"has been successfully generated!\n\n"
"Barcode is saved in the memory with name: {:20s}".format(color_metric,
frame_type,
barcode_type,
video_filename,
videoname) +
json_saved_success_message)
[docs] def disable_setup(self):
"""
Disable the letter box setup entry if user choose the Auto radio button
"""
self.high_ver_entry.config(state="disabled")
self.low_ver_entry.config(state="disabled")
self.left_hor_entry.config(state="disabled")
self.right_hor_entry.config(state="disabled")
[docs] def enable_setup(self):
"""
Enable the letter box setup entry if user choose the Manual radio button
"""
self.high_ver_entry.config(state="normal")
self.low_ver_entry.config(state="normal")
self.left_hor_entry.config(state="normal")
self.right_hor_entry.config(state="normal")