mirror of
https://github.com/deepfakes/faceswap
synced 2025-06-09 04:36:50 -04:00
- Mask Tool - Typing + BiSeNet mask update fix - Alignments Tool - Auto search for alignments file
169 lines
8.5 KiB
Python
169 lines
8.5 KiB
Python
#!/usr/bin/env python3
|
|
""" Command Line Arguments for tools """
|
|
import sys
|
|
import gettext
|
|
|
|
from typing import Any, List, Dict
|
|
|
|
from lib.cli.args import FaceSwapArgs
|
|
from lib.cli.actions import DirOrFileFullPaths, DirFullPaths, FileFullPaths, Radio, Slider
|
|
|
|
|
|
# LOCALES
|
|
_LANG = gettext.translation("tools.alignments.cli", localedir="locales", fallback=True)
|
|
_ = _LANG.gettext
|
|
|
|
|
|
_HELPTEXT = _("This command lets you perform various tasks pertaining to an alignments file.")
|
|
|
|
|
|
class AlignmentsArgs(FaceSwapArgs):
|
|
""" Class to parse the command line arguments for Alignments tool """
|
|
|
|
@staticmethod
|
|
def get_info() -> str:
|
|
""" Obtain command information.
|
|
|
|
Returns
|
|
-------
|
|
str
|
|
The help text for displaying in argparses help output
|
|
"""
|
|
return _("Alignments tool\nThis tool allows you to perform numerous actions on or using "
|
|
"an alignments file against its corresponding faceset/frame source.")
|
|
|
|
@staticmethod
|
|
def get_argument_list() -> List[Dict[str, Any]]:
|
|
""" Collect the argparse argument options.
|
|
|
|
Returns
|
|
-------
|
|
dict
|
|
The argparse command line options for processing by argparse
|
|
"""
|
|
frames_dir = _(" Must Pass in a frames folder/source video file (-fr).")
|
|
faces_dir = _(" Must Pass in a faces folder (-fc).")
|
|
frames_or_faces_dir = _(" Must Pass in either a frames folder/source video file OR a"
|
|
"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 = []
|
|
argument_list.append(dict(
|
|
opts=("-j", "--job"),
|
|
action=Radio,
|
|
type=str,
|
|
choices=("draw", "extract", "from-faces", "missing-alignments", "missing-frames",
|
|
"multi-faces", "no-faces", "remove-faces", "rename", "sort", "spatial"),
|
|
group=_("processing"),
|
|
required=True,
|
|
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|'from-faces': Generate alignment file(s) from a folder of extracted "
|
|
"faces. if the folder of faces comes from multiple sources, then multiple "
|
|
"alignments files will be created. NB: for faces which have been extracted "
|
|
"folders of source images, rather than a video, a single alignments file will "
|
|
"be created as there is no way for the process to know how many folders of "
|
|
"images were originally used. You do not need to provide an alignments file "
|
|
"path to run this job. {3}"
|
|
"\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)))
|
|
argument_list.append(dict(
|
|
opts=("-o", "--output"),
|
|
action=Radio,
|
|
type=str,
|
|
choices=("console", "file", "move"),
|
|
group=_("processing"),
|
|
default="console",
|
|
help=_("R|How to output discovered items ('faces' and 'frames' only):"
|
|
"\nL|'console': Print the list of frames to the screen. (DEFAULT)"
|
|
"\nL|'file': Output the list of frames to a text file (stored within the "
|
|
"source directory)."
|
|
"\nL|'move': Move the discovered items to a sub-folder within the source "
|
|
"directory.")))
|
|
argument_list.append(dict(
|
|
opts=("-a", "--alignments_file"),
|
|
action=FileFullPaths,
|
|
dest="alignments_file",
|
|
type=str,
|
|
group=_("data"),
|
|
# hacky solution to not require alignments file if creating alignments from faces:
|
|
required=not any(val in sys.argv for val in ["from-faces", "-fr", "-frames_folder"]),
|
|
filetypes="alignments",
|
|
help=_("Full path to the alignments file to be processed. If you have input a "
|
|
"'frames_dir' and don't provide this option, the process will try to find the "
|
|
"alignments file at the default location. All jobs require an alignments file "
|
|
"with the exception of 'from-faces' when the alignments file will be generated "
|
|
"in the specified faces folder.")))
|
|
argument_list.append(dict(
|
|
opts=("-fc", "-faces_folder"),
|
|
action=DirFullPaths,
|
|
dest="faces_dir",
|
|
group=_("data"),
|
|
help=_("Directory containing extracted faces.")))
|
|
argument_list.append(dict(
|
|
opts=("-fr", "-frames_folder"),
|
|
action=DirOrFileFullPaths,
|
|
dest="frames_dir",
|
|
filetypes="video",
|
|
group=_("data"),
|
|
help=_("Directory containing source frames that faces were extracted from.")))
|
|
argument_list.append(dict(
|
|
opts=("-een", "--extract-every-n"),
|
|
type=int,
|
|
action=Slider,
|
|
dest="extract_every_n",
|
|
min_max=(1, 100),
|
|
default=1,
|
|
rounding=1,
|
|
group=_("extract"),
|
|
help=_("[Extract only] Extract every 'nth' frame. This option will skip frames when "
|
|
"extracting faces. For example a value of 1 will extract faces from every "
|
|
"frame, a value of 10 will extract faces from every 10th frame.")))
|
|
argument_list.append(dict(
|
|
opts=("-sz", "--size"),
|
|
type=int,
|
|
action=Slider,
|
|
min_max=(256, 1024),
|
|
rounding=64,
|
|
default=512,
|
|
group=_("extract"),
|
|
help=_("[Extract only] The output size of extracted faces.")))
|
|
argument_list.append(dict(
|
|
opts=("-m", "--min-size"),
|
|
type=int,
|
|
action=Slider,
|
|
min_max=(0, 200),
|
|
rounding=1,
|
|
default=0,
|
|
dest="min_size",
|
|
group=_("extract"),
|
|
help=_("[Extract only] Only extract faces that have been resized by this percent or "
|
|
"more to meet the specified extract size (`-sz`, `--size`). Useful for "
|
|
"excluding low-res images from a training set. Set to 0 to extract all faces. "
|
|
"Eg: For an extract size of 512px, A setting of 50 will only include faces "
|
|
"that have been resized from 256px or above. Setting to 100 will only extract "
|
|
"faces that have been resized from 512px or above. A setting of 200 will only "
|
|
"extract faces that have been downscaled from 1024px or above.")))
|
|
return argument_list
|