              rounding=10,
              type=int,
              dest="save_interval",
              default=0,
              group="output",
              help="Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off"))
          argument_list.append(dict(
              opts=("-dl", "--debug-landmarks"),
              action="store_true",
              dest="debug_landmarks",
              default=False,
 
</s> remove             help="R|Choose which action you want to perform. NB: All actions require an "
                 "alignments file (-a) to be passed in."
                 "\nL|'draw': Draw landmarks on frames in the selected folder/video. A subfolder "
                 "will be created within the frames folder to hold the output.{0}"
                 "\nL|'extract': Re-extract faces from the source frames/video based on alignment "
                 "data. This is a lot quicker than re-detecting faces. Can pass in the '-een' "
                 "(--extract-every-n) parameter to only extract every nth frame.{1}"
                 "\nL|'missing-alignments': Identify frames that do not exist in the alignments "
                 "file.{2}{0}"
                 "\nL|'missing-frames': Identify frames in the alignments file that do not appear "
                 "within the frames folder/video.{2}{0}"
                 "\nL|'multi-faces': Identify where multiple faces exist within the alignments "
                 "file.{2}{4}"
                 "\nL|'no-faces': Identify frames that exist within the alignment file but no "
                 "faces were detected.{2}{0}"
                 "\nL|'remove-faces': Remove deleted faces from an alignments file. The original "
                 "alignments file will be backed up.{3}"
                 "\nL|'rename' - Rename faces to correspond with their parent frame and position "
                 "index in the alignments file (i.e. how they are named after running extract).{3}"
                 "\nL|'sort': Re-index the alignments from left to right. For alignments with "
                 "multiple faces this will ensure that the left-most face is at index 0."
                 "\nL|'spatial': Perform spatial and temporal filtering to smooth alignments "
                 "(EXPERIMENTAL!)".format(frames_dir, frames_and_faces_dir, output_opts, faces_dir,
                                          frames_or_faces_dir)))
 </s> add             help=_("R|Choose which action you want to perform. NB: All actions require an "
                   "alignments file (-a) to be passed in."
                   "\nL|'draw': Draw landmarks on frames in the selected folder/video. A "
                   "subfolder will be created within the frames folder to hold the output.{0}"
                   "\nL|'extract': Re-extract faces from the source frames/video based on "
                   "alignment data. This is a lot quicker than re-detecting faces. Can pass in "
                   "the '-een' (--extract-every-n) parameter to only extract every nth frame.{1}"
                   "\nL|'missing-alignments': Identify frames that do not exist in the alignments "
                   "file.{2}{0}"
                   "\nL|'missing-frames': Identify frames in the alignments file that do not "
                   "appear within the frames folder/video.{2}{0}"
                   "\nL|'multi-faces': Identify where multiple faces exist within the alignments "
                   "file.{2}{4}"
                   "\nL|'no-faces': Identify frames that exist within the alignment file but no "
                   "faces were detected.{2}{0}"
                   "\nL|'remove-faces': Remove deleted faces from an alignments file. The "
                   "original alignments file will be backed up.{3}"
                   "\nL|'rename' - Rename faces to correspond with their parent frame and "
                   "position index in the alignments file (i.e. how they are named after running "
                   "extract).{3}"
                   "\nL|'sort': Re-index the alignments from left to right. For alignments with "
                   "multiple faces this will ensure that the left-most face is at index 0."
                   "\nL|'spatial': Perform spatial and temporal filtering to smooth alignments "
                   "(EXPERIMENTAL!)").format(frames_dir, frames_and_faces_dir, output_opts,
                                             faces_dir, frames_or_faces_dir))) </s> remove         argument_list.append({
            "opts": ("-a", "--alignments"),
            "action": FileFullPaths,
            "type": str,
            "group": "data",
            "required": True,
            "filetypes": "alignments",
            "help": "Full path to the alignments file to add the mask to. NB: if the mask already "
                    "exists in the alignments file it will be overwritten."})
        argument_list.append({
            "opts": ("-i", "--input"),
            "action": DirOrFileFullPaths,
            "type": str,
            "group": "data",
            "filetypes": "video",
            "required": True,
            "help": "Directory containing extracted faces, source frames, or a video file."})
        argument_list.append({
            "opts": ("-it", "--input-type"),
            "action": Radio,
            "type": str.lower,
            "choices": ("faces", "frames"),
            "dest": "input_type",
            "group": "data",
            "default": "frames",
            "help": "R|Whether the `input` is a folder of faces or a folder frames/video"
                    "\nL|faces: The input is a folder containing extracted faces."
                    "\nL|frames: The input is a folder containing frames or is a video"})
        argument_list.append({
            "opts": ("-M", "--masker"),
            "action": Radio,
            "type": str.lower,
            "choices": PluginLoader.get_available_extractors("mask"),
            "default": "extended",
            "group": "process",
            "help": "R|Masker to use."
                    "\nL|components: Mask designed to provide facial segmentation based on the "
                    "positioning of landmark locations. A convex hull is constructed around the "
                    "exterior of the landmarks to create a mask."
                    "\nL|extended: Mask designed to provide facial segmentation based on the "
                    "positioning of landmark locations. A convex hull is constructed around the "
                    "exterior of the landmarks and the mask is extended upwards onto the forehead."
                    "\nL|vgg-clear: Mask designed to provide smart segmentation of mostly frontal "
                    "faces clear of obstructions. Profile faces and obstructions may result in "
                    "sub-par performance."
                    "\nL|vgg-obstructed: Mask designed to provide smart segmentation of mostly "
                    "frontal faces. The mask model has been specifically trained to recognize "
                    "some facial obstructions (hands and eyeglasses). Profile faces may result in "
                    "sub-par performance."
                    "\nL|unet-dfl: Mask designed to provide smart segmentation of mostly frontal "
                    "faces. The mask model has been trained by community members and will need "
                    "testing for further description. Profile faces may result in sub-par "
                    "performance."})
        argument_list.append({
            "opts": ("-p", "--processing"),
            "action": Radio,
            "type": str.lower,
            "choices": ("all", "missing", "output"),
            "default": "missing",
            "group": "process",
            "help": "R|Whether to update all masks in the alignments files, only those faces "
                    "that do not already have a mask of the given `mask type` or just to output "
                    "the masks to the `output` location."
                    "\nL|all: Update the mask for all faces in the alignments file."
                    "\nL|missing: Create a mask for all faces in the alignments file where a mask "
                    "does not previously exist."
                    "\nL|output: Don't update the masks, just output them for review in the given "
                    "output folder."})
        argument_list.append({
            "opts": ("-o", "--output-folder"),
            "action": DirFullPaths,
            "dest": "output",
            "type": str,
            "group": "output",
            "help": "Optional output location. If provided, a preview of the masks created will "
                    "be output in the given folder."})
        argument_list.append({
            "opts": ("-b", "--blur_kernel"),
            "action": Slider,
            "type": int,
            "group": "output",
            "min_max": (0, 9),
            "default": 3,
            "rounding": 1,
            "help": "Apply gaussian blur to the mask output. Has the effect of smoothing the "
                    "edges of the mask giving less of a hard edge. the size is in pixels. This "
                    "value should be odd, if an even number is passed in then it will be rounded "
                    "to the next odd number. NB: Only effects the output preview. Set to 0 for "
                    "off"})
        argument_list.append({
            "opts": ("-t", "--threshold"),
            "action": Slider,
            "type": int,
            "group": "output",
            "min_max": (0, 50),
            "default": 4,
            "rounding": 1,
            "help": "Helps reduce 'blotchiness' on some masks by making light shades white "
                    "and dark shades black. Higher values will impact more of the mask. NB: "
                    "Only effects the output preview. Set to 0 for off"})
        argument_list.append({
            "opts": ("-ot", "--output-type"),
            "action": Radio,
            "type": str.lower,
            "choices": ("combined", "masked", "mask"),
            "default": "combined",
            "group": "output",
            "help": "R|How to format the output when processing is set to 'output'."
                    "\nL|combined: The image contains the face/frame, face mask and masked face."
                    "\nL|masked: Output the face/frame as rgba image with the face masked."
                    "\nL|mask: Only output the mask as a single channel image."})
        argument_list.append({
            "opts": ("-f", "--full-frame"),
            "action": "store_true",
            "default": False,
            "group": "output",
            "help": "R|Whether to output the whole frame or only the face box when using "
                    "output processing. Only has an effect when using frames as input."})
 </s> add         argument_list.append(dict(
            opts=("-a", "--alignments"),
            action=FileFullPaths,
            type=str,
            group=_("data"),
            required=True,
            filetypes="alignments",
            help=_("Full path to the alignments file to add the mask to. NB: if the mask already "
                   "exists in the alignments file it will be overwritten.")))
        argument_list.append(dict(
            opts=("-i", "--input"),
            action=DirOrFileFullPaths,
            type=str,
            group=_("data"),
            filetypes="video",
            required=True,
            help=_("Directory containing extracted faces, source frames, or a video file.")))
        argument_list.append(dict(
            opts=("-it", "--input-type"),
            action=Radio,
            type=str.lower,
            choices=("faces", "frames"),
            dest="input_type",
            group=_("data"),
            default="frames",
            help=_("R|Whether the `input` is a folder of faces or a folder frames/video"
                   "\nL|faces: The input is a folder containing extracted faces."
                   "\nL|frames: The input is a folder containing frames or is a video")))
        argument_list.append(dict(
            opts=("-M", "--masker"),
            action=Radio,
            type=str.lower,
            choices=PluginLoader.get_available_extractors("mask"),
            default="extended",
            group=_("process"),
            help=_("R|Masker to use."
                   "\nL|components: Mask designed to provide facial segmentation based on the "
                   "positioning of landmark locations. A convex hull is constructed around the "
                   "exterior of the landmarks to create a mask."
                   "\nL|extended: Mask designed to provide facial segmentation based on the "
                   "positioning of landmark locations. A convex hull is constructed around the "
                   "exterior of the landmarks and the mask is extended upwards onto the forehead."
                   "\nL|vgg-clear: Mask designed to provide smart segmentation of mostly frontal "
                   "faces clear of obstructions. Profile faces and obstructions may result in "
                   "sub-par performance."
                   "\nL|vgg-obstructed: Mask designed to provide smart segmentation of mostly "
                   "frontal faces. The mask model has been specifically trained to recognize "
                   "some facial obstructions (hands and eyeglasses). Profile faces may result in "
                   "sub-par performance."
                   "\nL|unet-dfl: Mask designed to provide smart segmentation of mostly frontal "
                   "faces. The mask model has been trained by community members and will need "
                   "testing for further description. Profile faces may result in sub-par "
                   "performance.")))
        argument_list.append(dict(
            opts=("-p", "--processing"),
            action=Radio,
            type=str.lower,
            choices=("all", "missing", "output"),
            default="missing",
            group=_("process"),
            help=_("R|Whether to update all masks in the alignments files, only those faces "
                   "that do not already have a mask of the given `mask type` or just to output "
                   "the masks to the `output` location."
                   "\nL|all: Update the mask for all faces in the alignments file."
                   "\nL|missing: Create a mask for all faces in the alignments file where a mask "
                   "does not previously exist."
                   "\nL|output: Don't update the masks, just output them for review in the given "
                   "output folder.")))
        argument_list.append(dict(
            opts=("-o", "--output-folder"),
            action=DirFullPaths,
            dest="output",
            type=str,
            group=_("output"),
            help=_("Optional output location. If provided, a preview of the masks created will "
                   "be output in the given folder.")))
        argument_list.append(dict(
            opts=("-b", "--blur_kernel"),
            action=Slider,
            type=int,
            group=_("output"),
            min_max=(0, 9),
            default=3,
            rounding=1,
            help=_("Apply gaussian blur to the mask output. Has the effect of smoothing the "
                   "edges of the mask giving less of a hard edge. the size is in pixels. This "
                   "value should be odd, if an even number is passed in then it will be rounded "
                   "to the next odd number. NB: Only effects the output preview. Set to 0 for "
                   "off")))
        argument_list.append(dict(
            opts=("-t", "--threshold"),
            action=Slider,
            type=int,
            group=_("output"),
            min_max=(0, 50),
            default=4,
            rounding=1,
            help=_("Helps reduce 'blotchiness' on some masks by making light shades white "
                   "and dark shades black. Higher values will impact more of the mask. NB: "
                   "Only effects the output preview. Set to 0 for off")))
        argument_list.append(dict(
            opts=("-ot", "--output-type"),
            action=Radio,
            type=str.lower,
            choices=("combined", "masked", "mask"),
            default="combined",
            group=_("output"),
            help=_("R|How to format the output when processing is set to 'output'."
                   "\nL|combined: The image contains the face/frame, face mask and masked face."
                   "\nL|masked: Output the face/frame as rgba image with the face masked."
                   "\nL|mask: Only output the mask as a single channel image.")))
        argument_list.append(dict(
            opts=("-f", "--full-frame"),
            action="store_true",
            default=False,
            group=_("output"),
            help=_("R|Whether to output the whole frame or only the face box when using "
                   "output processing. Only has an effect when using frames as input."))) </s> remove             group="Face Processing",
            help="If you have not cleansed your alignments file, then you can filter out faces "
                 "by defining a folder here that contains the faces extracted from your input "
                 "files/video. If this folder is defined, then only faces that exist within "
                 "your alignments file and also exist within the specified folder will be "
                 "converted. Leaving this blank will convert all faces that exist within the "
                 "alignments file."))
 </s> add             group=_("Face Processing"),
            help=_("If you have not cleansed your alignments file, then you can filter out faces "
                   "by defining a folder here that contains the faces extracted from your input "
                   "files/video. If this folder is defined, then only faces that exist within "
                   "your alignments file and also exist within the specified folder will be "
                   "converted. Leaving this blank will convert all faces that exist within the "
                   "alignments file."))) </s> remove             group="Face Processing",
            help="Filters out faces detected below this size. Length, in pixels across the "
                 "diagonal of the bounding box. Set to 0 for off"))
 </s> add             group=_("Face Processing"),
            help=_("Filters out faces detected below this size. Length, in pixels across the "
                   "diagonal of the bounding box. Set to 0 for off"))) </s> remove             group="augmentation",
            help="Warping is integral to training the Neural Network. This option should only be "
                 "enabled towards the very end of training to try to bring out more detail. Think "
                 "of it as 'fine-tuning'. Enabling this option from the beginning is likely to "
                 "kill a model and lead to terrible results."))
 </s> add             group=_("augmentation"),
            help=_("Warping is integral to training the Neural Network. This option should only "
                   "be enabled towards the very end of training to try to bring out more detail. "
                   "Think of it as 'fine-tuning'. Enabling this option from the beginning is "
                   "likely to kill a model and lead to terrible results.")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
              rounding=10,
              type=int,
              dest="save_interval",
              default=0,
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
            group=_("output"),
            help=_("Automatically save the alignments file after a set amount of frames. By "
                   "default the alignments file is only saved at the end of the extraction "
                   "process. NB: If extracting in 2 passes then the alignments file will only "
                   "start to be saved out during the second pass. WARNING: Don't interrupt the "
                   "script when writing the file because it might get corrupted. Set to 0 to "
                   "turn off")))
          argument_list.append(dict(
              opts=("-dl", "--debug-landmarks"),
              action="store_true",
              dest="debug_landmarks",
              default=False,
keep keep keep keep replace replace replace replace replace replace replace keep keep keep keep keep
 Add Locale support for cli arguments 
lib/cli/args.py