                   "\n\t facehull: Face cutout based on landmarks")
          self.add_item(
              section=section, title="mask_blur", datatype=bool, default=False, group="mask",
              info="Apply gaussian blur to the mask input. This has the effect of smoothing the "
                   "edges of the mask, which can help with poorly calculated masks, and give less "
                   "of a hard edge to the predicted mask.")
          self.add_item(
              section=section, title="icnr_init", datatype=bool,
              default=False, group="initialization",
              info="Use ICNR to tile the default initializer in a repeating pattern. "
                   "This strategy is designed for pairing with sub-pixel / pixel shuffler "
 
</s> remove             section=section, title="mask_blur", datatype=bool, default=False, group="mask",
 </s> add             section=section, title="mask_blur_kernel", datatype=int, min_max=(0, 9),
            rounding=1, default=3, group="mask", </s> remove             choices=get_available_masks(), group="mask",
            info="The mask to be used for training:"
                 "\n\t none: Doesn't use any mask."
                 "\n\t components: An improved face hull mask using a facehull of 8 facial parts"
                 "\n\t dfl_full: An improved face hull mask using a facehull of 3 facial parts"
                 "\n\t extended: Based on components mask. Extends the eyebrow points to further "
                 "up the forehead. May perform badly on difficult angles."
                 "\n\t facehull: Face cutout based on landmarks")
 </s> add             choices=PluginLoader.get_available_extractors("mask", add_none=True), group="mask",
            gui_radio=True,
            info="The mask to be used for training. If you have selected 'Learn Mask' or "
                 "'Penalized Mask Loss' you must select a value other than 'none'. The required "
                 "mask should have been selected as part of the Extract process. If it does not "
                 "exist in the alignments file then it will be generated prior to training "
                 "commencing."
                 "\n\tnone: Don't use a mask."
                 "\n\tcomponents: 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."
                 "\n\textended: 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."
                 "\n\tvgg-clear: Mask designed to provide smart segmentation of mostly frontal "
                 "faces clear of obstructions. Profile faces and obstructions may result in "
                 "sub-par performance."
                 "\n\tvgg-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."
                 "\n\tunet-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.") </s> remove             "help": "R|Masker to use. NB: Masker is not currently used by the rest of the process "
                    "but this will store a mask in the alignments file for use when it has been "
                    "implemented."
 </s> add             "help": "R|Masker to use. NB - masks generated here can be used for training, and "
                    "converting with the 'predicted' mask. Availability of all masks specified "
                    "here for convert is coming soon." </s> remove                    "\nIf you are training with a mask or using 'warp to landmarks' then every "
 </s> add                    "\nIf you are using 'warp to landmarks' then every " </s> remove             indices = [idx for idx, hsh in enumerate(src_points) if hsh is None]
            missing = [filenames[idx] for idx in indices]
 </s> add             missing = [filenames[idx] for idx, pts in enumerate(src_points) if pts is None]
                 "edges of the mask, which can help with poorly calculated masks and give less "
                 "of a hard edge to the predicted mask. The size is in pixels (calculated from "
                 "a 128px mask). Set to 0 to not apply gaussian blur. This value should be odd, "
                 "if an even number is passed in then it will be rounded to the next odd number.")
        self.add_item(
            section=section, title="mask_threshold", datatype=int, default=4,
            min_max=(0, 50), rounding=1, group="mask",
            info="Sets pixels that are near white to white and near black to black. Set to 0 for "
                 "off.")
        self.add_item(
            section=section, title="learn_mask", datatype=bool, default=False, group="mask",
            info="Dedicate a portion of the model to learning how to duplicate the input "
                 "mask. Increases VRAM usage in exchange for learning a quick ability to try "
                 "to replicate more complex mask models.")
                   "\n\t facehull: Face cutout based on landmarks")
          self.add_item(
              section=section, title="mask_blur", datatype=bool, default=False, group="mask",
              info="Apply gaussian blur to the mask input. This has the effect of smoothing the "
                 "edges of the mask, which can help with poorly calculated masks and give less "
                 "of a hard edge to the predicted mask. The size is in pixels (calculated from "
                 "a 128px mask). Set to 0 to not apply gaussian blur. This value should be odd, "
                 "if an even number is passed in then it will be rounded to the next odd number.")
        self.add_item(
            section=section, title="mask_threshold", datatype=int, default=4,
            min_max=(0, 50), rounding=1, group="mask",
            info="Sets pixels that are near white to white and near black to black. Set to 0 for "
                 "off.")
        self.add_item(
            section=section, title="learn_mask", datatype=bool, default=False, group="mask",
            info="Dedicate a portion of the model to learning how to duplicate the input "
                 "mask. Increases VRAM usage in exchange for learning a quick ability to try "
                 "to replicate more complex mask models.")
                 "edges of the mask, which can help with poorly calculated masks and give less "
                 "of a hard edge to the predicted mask. The size is in pixels (calculated from "
                 "a 128px mask). Set to 0 to not apply gaussian blur. This value should be odd, "
                 "if an even number is passed in then it will be rounded to the next odd number.")
        self.add_item(
            section=section, title="mask_threshold", datatype=int, default=4,
            min_max=(0, 50), rounding=1, group="mask",
            info="Sets pixels that are near white to white and near black to black. Set to 0 for "
                 "off.")
        self.add_item(
            section=section, title="learn_mask", datatype=bool, default=False, group="mask",
            info="Dedicate a portion of the model to learning how to duplicate the input "
                 "mask. Increases VRAM usage in exchange for learning a quick ability to try "
                 "to replicate more complex mask models.")
          self.add_item(
              section=section, title="icnr_init", datatype=bool,
              default=False, group="initialization",
              info="Use ICNR to tile the default initializer in a repeating pattern. "
                   "This strategy is designed for pairing with sub-pixel / pixel shuffler "
keep keep keep keep replace replace keep keep keep keep keep
 Smart Masks - Training Implementation (#914)

* Smart Masks - Training

- Reinstate smart mask training code
- Reinstate mask_type back to model.config
- change 'replicate_input_mask to 'learn_mask'
- Add learn mask option
- Add mask loading from alignments to plugins.train.trainer
- Add mask_blur and mask threshold options
- _base.py - Pass mask options through training_opts dict
- plugins.train.model - check for mask_type not None for learn_mask and penalized_mask_loss
- Limit alignments loading to just those faces that appear in the training folder
- Raise error if not all training images have an alignment, and alignment file is required
- lib.training_data - Mask generation code
- lib.faces_detect - cv2 dimension stripping bugfix
- Remove cv2 linting code

* Update mask helptext in cli.py

* Fix Warp to Landmarks
Remove SHA1 hashing from training data

* Update mask training config

* Capture missing masks at training init

* lib.image.read_image_batch - Return filenames with batch for ordering

* scripts.train - Documentation

* plugins.train.trainer - documentation

* Ensure backward compatibility.
Fix convert for new predicted masks

* Update removed masks to components for legacy models. 
plugins/train/_config.py