                                 "faces folder (-fr or -fc).")
          frames_and_faces_dir = (" Must Pass in a frames folder/source video file AND a faces "
                                  "folder (-fr and -fc).")
          output_opts = " Use the output option (-o) to process results."
          align_eyes = " Can optionally use the align-eyes switch (-ae)."
          argument_list = list()
          argument_list.append(dict(
              opts=("-j", "--job"),
              action=Radio,
              type=str,
 
</s> remove             choices=("dfl", "draw", "extract", "merge", "missing-alignments", "missing-frames",
                     "leftover-faces", "multi-faces", "no-faces", "remove-faces", "remove-frames",
                     "rename", "sort", "spatial", "update-hashes"),
 </s> add             choices=("draw", "extract", "merge", "missing-alignments", "missing-frames",
                     "leftover-faces", "multi-faces", "no-faces", "remove-faces", "rename", "sort",
                     "spatial", "update-hashes"), </s> remove                  "(--extract-every-n) parameter to only extract every nth frame.{1}{2}"
 </s> add                  "(--extract-every-n) parameter to only extract every nth frame.{1}" </s> remove                  "\nL|'dfl': Create an alignments file from faces extracted from DeepFaceLab. "
                 "Specify 'dfl' as the 'alignments file' entry and the folder containing the dfl "
                 "faces as the 'faces folder' ('-a dfl -fc <source faces folder>')"
 </s> add  </s> remove                  "file.{3}{0}"
 </s> add                  "file.{2}{0}" </s> remove         argument_list.append({"opts": ('-i', '--input'),
                              "action": DirFullPaths,
                              "dest": "input_dir",
                              "group": "data",
                              "help": "Input directory of aligned faces.",
                              "required": True})

        argument_list.append({"opts": ('-o', '--output'),
                              "action": DirFullPaths,
                              "dest": "output_dir",
                              "group": "data",
                              "help": "Output directory for sorted aligned "
                                      "faces."})

        argument_list.append({"opts": ('-s', '--sort-by'),
                              "action": Radio,
                              "type": str,
                              "choices": ("blur", "face", "face-cnn", "face-cnn-dissim",
                                          "face-yaw", "hist", "hist-dissim", "color-gray",
                                          "color-luma", "color-green", "color-orange"),
                              "dest": 'sort_method',
                              "group": "sort settings",
                              "default": "face",
                              "help": "R|Sort by method. Choose how images are sorted. "
                                      "\nL|'blur': Sort faces by blurriness."
                                      "\nL|'face': Use VGG Face to sort by face similarity. This "
                                      "uses a pairwise clustering algorithm to check the "
                                      "distances between 4096 features on every face in your set "
                                      "and order them appropriately. WARNING: On very large "
                                      "datasets it is possible to run out of memory performing "
                                      "this calculation."
                                      "\nL|'face-cnn': Sort faces by their landmarks. You can "
                                      "adjust the threshold with the '-t' (--ref_threshold) "
                                      "option."
                                      "\nL|'face-cnn-dissim': Like 'face-cnn' but sorts by "
                                      "dissimilarity."
                                      "\nL|'face-yaw': Sort faces by Yaw (rotation left to right)."
                                      "\nL|'hist': Sort faces by their color histogram. You can "
                                      "adjust the threshold with the '-t' (--ref_threshold) "
                                      "option."
                                      "\nL|'hist-dissim': Like 'hist' but sorts by dissimilarity."
                                      "\nL|'color-gray': Sort images by the average intensity of "
                                      "the converted grayscale color channel."
                                      "\nL|'color-luma': Sort images by the average intensity of "
                                      "the converted Y color channel. Bright lighting and "
                                      "oversaturated images will be ranked first."
                                      "\nL|'color-green': Sort images by the average intensity of "
                                      "the converted Cg color channel. Green images will be "
                                      "ranked first and red images will be last."
                                      "\nL|'color-orange': Sort images by the average intensity "
                                      "of the converted Co color channel. Orange images will be "
                                      "ranked first and blue images will be last."
                                      "\nDefault: hist"})
        argument_list.append({"opts": ('-k', '--keep'),
                              "action": 'store_true',
                              "dest": 'keep_original',
                              "default": False,
                              "group": "output",
                              "help": "Keeps the original files in the input "
                                      "directory. Be careful when using this "
                                      "with rename grouping and no specified "
                                      "output directory as this would keep "
                                      "the original and renamed files in the "
                                      "same directory."})
        argument_list.append({"opts": ('-t', '--ref_threshold'),
                              "action": Slider,
                              "min_max": (-1.0, 10.0),
                              "rounding": 2,
                              "type": float,
                              "dest": 'min_threshold',
                              "group": "sort settings",
                              "default": -1.0,
                              "help": "Float value. "
                                      "Minimum threshold to use for grouping comparison with "
                                      "'face-cnn' and 'hist' methods. The lower the value the "
                                      "more discriminating the grouping is. Leaving -1.0 will "
                                      "allow the program set the default value automatically. "
                                      "For face-cnn 7.2 should be enough, with 4 being very "
                                      "discriminating. For hist 0.3 should be enough, with 0.2 "
                                      "being very discriminating. Be careful setting a value "
                                      "that's too low in a directory with many images, as this "
                                      "could result in a lot of directories being created. "
                                      "Defaults: face-cnn 7.2, hist 0.3"})

        argument_list.append({"opts": ('-fp', '--final-process'),
                              "action": Radio,
                              "type": str,
                              "choices": ("folders", "rename"),
                              "dest": 'final_process',
                              "default": "rename",
                              "group": "output",
                              "help": "R|Default: rename."
                                      "\nL|'folders': files are sorted using "
                                      "the -s/--sort-by method, then they "
                                      "are organized into folders using "
                                      "the -g/--group-by grouping method."
                                      "\nL|'rename': files are sorted using "
                                      "the -s/--sort-by then they are "
                                      "renamed."})

        argument_list.append({"opts": ('-g', '--group-by'),
                              "action": Radio,
                              "type": str,
                              "choices": ("blur", "face-cnn", "face-yaw", "hist"),
                              "dest": 'group_method',
                              "group": "output",
                              "default": "hist",
                              "help": "Group by method. "
                                      "When -fp/--final-processing by "
                                      "folders choose the how the images are "
                                      "grouped after sorting. "
                                      "Default: hist"})

        argument_list.append({"opts": ('-b', '--bins'),
                              "action": Slider,
                              "min_max": (1, 100),
                              "rounding": 1,
                              "type": int,
                              "dest": 'num_bins',
                              "group": "output",
                              "default": 5,
                              "help": "Integer value. "
                                      "Number of folders that will be used "
                                      "to group by blur and face-yaw. "
                                      "For blur folder 0 will be the least "
                                      "blurry, while the last folder will be "
                                      "the blurriest. "
                                      "For face-yaw the number of bins is by "
                                      "how much 180 degrees is divided. So "
                                      "if you use 18, then each folder will "
                                      "be a 10 degree increment. Folder 0 "
                                      "will contain faces looking the most "
                                      "to the left whereas the last folder "
                                      "will contain the faces looking the "
                                      "most to the right. "
                                      "If the number of images doesn't "
                                      "divide evenly into the number of "
                                      "bins, the remaining images get put in "
                                      "the last bin."
                                      "Default value: 5"})

        argument_list.append({"opts": ('-l', '--log-changes'),
                              "action": 'store_true',
                              "group": "settings",
                              "default": False,
                              "help": "Logs file renaming changes if "
                                      "grouping by renaming, or it logs the "
                                      "file copying/movement if grouping by "
                                      "folders. If no log file is specified "
                                      "with '--log-file', then a "
                                      "'sort_log.json' file will be created "
                                      "in the input directory."})

        argument_list.append({"opts": ('-lf', '--log-file'),
                              "action": SaveFileFullPaths,
                              "filetypes": "alignments",
                              "group": "settings",
                              "dest": 'log_file_path',
                              "default": 'sort_log.json',
                              "help": "Specify a log file to use for saving "
                                      "the renaming or grouping information. "
                                      "If specified extension isn't 'json' "
                                      "or 'yaml', then json will be used as "
                                      "the serializer, with the supplied "
                                      "filename. "
                                      "Default: sort_log.json"})
 </s> add         argument_list.append(dict(
            opts=('-i', '--input'),
            action=DirFullPaths,
            dest="input_dir",
            group="data",
            help="Input directory of aligned faces.",
            required=True))
        argument_list.append(dict(
            opts=('-o', '--output'),
            action=DirFullPaths,
            dest="output_dir",
            group="data",
            help="Output directory for sorted aligned faces."))
        argument_list.append(dict(
            opts=('-a', '--alignments'),
            action=FileFullPaths,
            filetypes="alignments",
            type=str,
            dest="alignments_path",
            group="data",
            help="Optional path to an alignments file. This is only used for the 'sort-by face' "
                 "method. If not provided, the default location will be scanned. If the file "
                 "still cannot be located, then the sorting process will analyze the full-head "
                 "extract images, which will lead to vastly inferior results."))
        argument_list.append(dict(
            opts=('-s', '--sort-by'),
            action=Radio,
            type=str,
            choices=("blur", "face", "face-cnn", "face-cnn-dissim", "face-yaw", "hist",
                     "hist-dissim", "color-gray", "color-luma", "color-green", "color-orange"),
            dest='sort_method',
            group="sort settings",
            default="face",
            help="R|Sort by method. Choose how images are sorted. "
                 "\nL|'blur': Sort faces by blurriness."
                 "\nL|'face': Use VGG Face to sort by face similarity. This uses a pairwise "
                 "clustering algorithm to check the distances between 512 features on every face "
                 "in your set and order them appropriately. NB: You should provide an alignments "
                 "file if using this method. Not doing so will lead to vastly inferior results."
                 "\nL|'face-cnn': Sort faces by their landmarks. You can adjust the threshold "
                 "with the '-t' (--ref_threshold) option."
                 "\nL|'face-cnn-dissim': Like 'face-cnn' but sorts by dissimilarity."
                 "\nL|'face-yaw': Sort faces by Yaw (rotation left to right)."
                 "\nL|'hist': Sort faces by their color histogram. You can adjust the threshold "
                 "with the '-t' (--ref_threshold) option."
                 "\nL|'hist-dissim': Like 'hist' but sorts by dissimilarity."
                 "\nL|'color-gray': Sort images by the average intensity of the converted "
                 "grayscale color channel."
                 "\nL|'color-luma': Sort images by the average intensity of the converted Y color "
                 "channel. Bright lighting and oversaturated images will be ranked first."
                 "\nL|'color-green': Sort images by the average intensity of the converted Cg "
                 "color channel. Green images will be ranked first and red images will be last."
                 "\nL|'color-orange': Sort images by the average intensity of the converted Co "
                 "color channel. Orange images will be ranked first and blue images will be last."
                 "\nDefault: hist"))
        argument_list.append(dict(
            opts=('-k', '--keep'),
            action='store_true',
            dest='keep_original',
            default=False,
            group="output",
            help="Keeps the original files in the input directory. Be careful when using this "
                 "with rename grouping and no specified output directory as this would keep the "
                 "original and renamed files in the same directory."))
        argument_list.append(dict(
            opts=('-t', '--ref_threshold'),
            action=Slider,
            min_max=(-1.0, 10.0),
            rounding=2,
            type=float,
            dest='min_threshold',
            group="sort settings",
            default=-1.0,
            help="Float value. Minimum threshold to use for grouping comparison with 'face-cnn' "
                 "and 'hist' methods. The lower the value the more discriminating the grouping "
                 "is. Leaving -1.0 will allow the program set the default value automatically. "
                 "For face-cnn 7.2 should be enough, with 4 being very discriminating. For hist "
                 "0.3 should be enough, with 0.2 being very discriminating. Be careful setting a "
                 "value that's too low in a directory with many images, as this could result in a "
                 "lot of directories being created. Defaults: face-cnn 7.2, hist 0.3"))
        argument_list.append(dict(
            opts=('-fp', '--final-process'),
            action=Radio,
            type=str,
            choices=("folders", "rename"),
            dest='final_process',
            default="rename",
            group="output",
            help="R|Default: rename."
                 "\nL|'folders': files are sorted using the -s/--sort-by method, then they are "
                 "organized into folders using the -g/--group-by grouping method."
                 "\nL|'rename': files are sorted using the -s/--sort-by then they are renamed."))
        argument_list.append(dict(
            opts=('-g', '--group-by'),
            action=Radio,
            type=str,
            choices=("blur", "face-cnn", "face-yaw", "hist"),
            dest='group_method',
            group="output",
            default="hist",
            help="Group by method. When -fp/--final-processing by folders choose the how the "
                 "images are grouped after sorting. Default: hist"))
        argument_list.append(dict(
            opts=('-b', '--bins'),
            action=Slider,
            min_max=(1, 100),
            rounding=1,
            type=int,
            dest='num_bins',
            group="output",
            default=5,
            help="Integer value. Number of folders that will be used to group by blur and "
                 "face-yaw. For blur folder 0 will be the least blurry, while the last folder "
                 "will be the blurriest. For face-yaw the number of bins is by how much 180 "
                 "degrees is divided. So if you use 18, then each folder will be a 10 degree "
                 "increment. Folder 0 will contain faces looking the most to the left whereas the "
                 "last folder will contain the faces looking the most to the right. If the number "
                 "of images doesn't divide evenly into the number of bins, the remaining images "
                 "get put in the last bin. Default value: 5"))
        argument_list.append(dict(
            opts=('-l', '--log-changes'),
            action='store_true',
            group="settings",
            default=False,
            help="Logs file renaming changes if grouping by renaming, or it logs the file "
                 "copying/movement if grouping by folders. If no log file is specified  with "
                 "'--log-file', then a 'sort_log.json' file will be created in the input "
                 "directory."))
        argument_list.append(dict(
            opts=('-lf', '--log-file'),
            action=SaveFileFullPaths,
            filetypes="alignments",
            group="settings",
            dest='log_file_path',
            default='sort_log.json',
            help="Specify a log file to use for saving the renaming or grouping information. If "
                 "specified extension isn't 'json' or 'yaml', then json will be used as the "
                 "serializer, with the supplied filename. Default: sort_log.json"))
                                 "faces folder (-fr or -fc).")
          frames_and_faces_dir = (" Must Pass in a frames folder/source video file AND a faces "
                                  "folder (-fr and -fc).")
          output_opts = " Use the output option (-o) to process results."

          argument_list = list()
          argument_list.append(dict(
              opts=("-j", "--job"),
              action=Radio,
              type=str,
keep keep keep keep replace keep keep keep keep keep
 Extract - Increase area and move centering (#1095)

* Extract
  - Implement aligner re-feeding
  - Add extract type to pipeline.ExtractMedia
  - Add pose annotation to debug
* Convert
  - implement centering
  - remove usage of feed and reference face properties
  - Remove distributed option from convert
  - Force update of alignments file on legacy receive
* Train
  - Resize preview image to model output size
  - Force legacy centering if centering does not exist in model's state file
  - Enable training on legacy face sets

* Alignments Tool
  - Update draw to include head/pose
  - Remove DFL drop + linting
  - Remove remove-frames job
  - remove align-eyes option
  - Update legacy masks to new extract type
  - Exit if attempting to merge version 1.0 alignments files with version 2.0 alignments files
  - Re-generate thumbnails on legacy upgrade
* Mask Tool
  - Update for new extract + bugfix full frame
* Manual Tool
  - Update to new extraction method
   - Disable legacy alignments,
   - extract box bugfix
   - extract faces - size to 512 and center on head
* Preview Tool
  - Display based on model centering
* Sort Tool
  - Use alignments for sort by face

* lib.aligner
  - Add Pose Class
  - Add AlignedFace Class
  - center _MEAN_FACE on x
  - Add meta information with versioning to alignments file
  - lib.aligner.get_align_matrix to use landmarks not face
  - Refactor aligned faces in lib.faces_detect
* lib.logger
  - larger file log padding
* lib.config
  - Fix global changeable_items
* lib.face_filter
  - Use new extracted face images
* lib.image
  - bump thumbnail default size to 96px 
tools/alignments/cli.py