Public functions
load_resources
Fix the model files.
Currently, both HaarCascade classifiers and DNN are supported. Add
as many models as wished; their results are combined.
The given model(s) is/are enabled if there's an option to indicate it,
i.e. one starting by "model:".
Parameters
- model1: (str) Filename of a model
- args: other models for face detection
View Source
def load_resources(self, model1, *args, **kwargs):
"""Fix the model files.
Currently, both HaarCascade classifiers and DNN are supported. Add
as many models as wished; their results are combined.
The given model(s) is/are enabled if there's an option to indicate it,
i.e. one starting by "model:".
:param model1: (str) Filename of a model
:param args: other models for face detection
"""
self.__fdi.load_model(model1, *args)
all_models = [model1]
for filename in args:
all_models.append(filename)
for key in self._options:
if key.startswith('model:'):
model_name = key.split(':')[1]
if any([model_name in m for m in all_models]) is True:
self.set_enable_model(model_name, self._options[key])
fix_options
Fix all options.
Parameters
View Source
def fix_options(self, options):
"""Fix all options.
:param options: (sppasOption)
"""
for opt in options:
key = opt.get_key()
if key == 'nbest':
self.set_max_faces(opt.get_value())
elif key == 'score':
self.set_min_score(opt.get_value())
elif key == 'csv':
self.set_out_csv(opt.get_value())
elif key == 'tag':
self.set_img_tag(opt.get_value())
elif key == 'crop':
self.set_img_crop(opt.get_value())
elif key == 'portrait':
self.set_img_portrait(opt.get_value())
elif key == 'folder':
self.set_out_folder(opt.get_value())
elif key == 'width':
self.set_img_width(opt.get_value())
elif key == 'height':
self.set_img_height(opt.get_value())
elif key.startswith('model:'):
self._options[key] = opt.get_value()
self.set_enable_model(key.split(':')[1], opt.get_value())
elif 'pattern' in key:
self._options[key] = opt.get_value()
else:
raise AnnotationOptionError(key)
set_max_faces
Fix the maximum number of expected faces in an image.
Parameters
- value: (int) Number of faces
View Source
def set_max_faces(self, value):
"""Fix the maximum number of expected faces in an image.
:param value: (int) Number of faces
"""
value = int(value)
self.__fdv.set_filter_best(value)
self.__fdi.filter_best(value)
self._options['nbest'] = value
set_min_score
Fix the minimum score to accept a face in an image.
Parameters
- value: (float) Min confidence score of face detection result
View Source
def set_min_score(self, value):
"""Fix the minimum score to accept a face in an image.
:param value: (float) Min confidence score of face detection result
"""
value = float(value)
self.__fdv.set_filter_confidence(value)
self.__fdi.filter_confidence(value)
self._options['score'] = value
set_out_csv
The result includes a CSV file.
Parameters
- out_csv: (bool) Create a CSV file when detecting
View Source
def set_out_csv(self, out_csv=False):
"""The result includes a CSV file.
:param out_csv: (bool) Create a CSV file when detecting
"""
self.__img_writer.set_options(csv=out_csv)
self.__video_writer.set_options(csv=out_csv)
self._options['csv'] = out_csv
self.__img_writer.set_options(xra=not out_csv)
self.__video_writer.set_options(xra=not out_csv)
self._options['xra'] = not out_csv
set_img_tag
Surround the faces with a square.
Parameters
- value: (bool) Tag the images
View Source
def set_img_tag(self, value=True):
"""Surround the faces with a square.
:param value: (bool) Tag the images
"""
value = bool(value)
self.__video_writer.set_options(tag=value)
self._options['tag'] = value
set_img_crop
Create an image/video for each detected person.
Parameters
- value: (bool) Crop the images
View Source
def set_img_crop(self, value=True):
"""Create an image/video for each detected person.
:param value: (bool) Crop the images
"""
value = bool(value)
self.__video_writer.set_options(crop=value)
self._options['crop'] = value
set_img_width
Width of the resulting images/video.
Parameters
- value: (int) Number of pixels
View Source
def set_img_width(self, value):
"""Width of the resulting images/video.
:param value: (int) Number of pixels
"""
self.__video_writer.set_options(width=value)
self._options['width'] = value
set_img_height
Height of the resulting images/video.
Parameters
- value: (int) Number of pixel
View Source
def set_img_height(self, value):
"""Height of the resulting images/video.
:param value: (int) Number of pixel
"""
self.__video_writer.set_options(height=value)
self._options['height'] = value
set_img_portrait
Result is the portrait instead of the face.
Parameters
View Source
def set_img_portrait(self, value):
"""Result is the portrait instead of the face.
:param value: (bool) True
"""
value = bool(value)
self._options['portrait'] = value
self.__fdv.set_portrait(value)
set_out_folder
The result includes a folder with image files -- if video input.
Parameters
- out_folder: (bool) Create a folder with image files when detecting
View Source
def set_out_folder(self, out_folder=False):
"""The result includes a folder with image files -- if video input.
:param out_folder: (bool) Create a folder with image files when detecting
"""
self.__video_writer.set_options(folder=out_folder)
self._options['folder'] = out_folder
set_enable_model
Enable or disable the use of a detection model.
Parameters
- model_name: (str) model filename without path (model basename).
- value: (bool) True to enable.
View Source
def set_enable_model(self, model_name, value=True):
"""Enable or disable the use of a detection model.
:param model_name: (str) model filename without path (model basename).
:param value: (bool) True to enable.
"""
value = bool(value)
success = self.__fdi.enable_recognizer(model_name, value)
if success is False and value is True:
self.logfile.print_message("Model {:s} can't be enabled.".format(model_name), indent=2, status=annots.warning)
get_nb_recognizers
Return the number of initialized object recognizers for video.
View Source
def get_nb_recognizers(self):
"""Return the number of initialized object recognizers for video."""
return self.__fdi.get_nb_recognizers()
get_nb_enabled_recognizers
Return the number of enabled object recognizers.
View Source
def get_nb_enabled_recognizers(self):
"""Return the number of enabled object recognizers."""
return self.__fdi.get_nb_enabled_recognizers()
get_recognizer_names
Return the name of all the initialized recognizers.
View Source
def get_recognizer_names(self):
"""Return the name of all the initialized recognizers."""
return self.__fdi.get_recognizer_names()
get_enabled_recognizer_names
Return the name of all the initialized recognizers.
View Source
def get_enabled_recognizer_names(self):
"""Return the name of all the initialized recognizers. """
return self.__fdi.get_enabled_recognizer_names()
image_face_detect
Get the image, detect faces and write results.
Parameters
- image: (str or sppasImage) Image filename
- output: (str) The output name for the image
Returns
- (list) the coordinates of all detected faces or created filenames
View Source
def image_face_detect(self, image, output=None):
"""Get the image, detect faces and write results.
:param image: (str or sppasImage) Image filename
:param output: (str) The output name for the image
:return: (list) the coordinates of all detected faces or created filenames
"""
if isinstance(image, sppasImage) is False:
image = sppasImage(filename=image)
self.__fdi.detect(image)
if self._options['portrait'] is True:
try:
self.__fdi.to_portrait(image)
except Exception as e:
self.logfile.print_message("Faces can't be scaled to portrait: {}".format(str(e)), indent=2, status=annots.error)
coords = [c.copy() for c in self.__fdi]
if output is not None:
output_file = self.fix_out_file_ext(output, out_format='IMAGE')
new_files = self.__img_writer.write(image, coords, output_file, self.get_output_pattern())
return new_files
return coords
get_inputs
Return the media filenames.
Parameters
Raises
NoInputError
Returns
- (str) Name of the media file
View Source
def get_inputs(self, input_files):
"""Return the media filenames.
:param input_files: (list)
:raise: NoInputError
:return: (str) Name of the media file
"""
media_ext = self.get_input_extensions()
media = None
for filename in input_files:
fn, fe = os.path.splitext(filename)
if media is None and fe in media_ext[0]:
return filename
logging.error('Neither a video nor an image was found.')
raise NoInputError
run
Run the automatic annotation process on a single input.
Parameters
- input_files: (list of str) Video or image file
- output: (str) the output name
Returns
- (list of sppasCoords) Coordinates of detected faces or filenames
View Source
def run(self, input_files, output=None):
"""Run the automatic annotation process on a single input.
:param input_files: (list of str) Video or image file
:param output: (str) the output name
:returns: (list of sppasCoords) Coordinates of detected faces or filenames
"""
media_file = self.get_inputs(input_files)
self.__video_writer.set_image_extension(self._out_extensions['IMAGE'])
self.__video_writer.set_video_extension(self._out_extensions['VIDEO'])
self.__video_writer.close()
fn, ext = os.path.splitext(media_file)
result = list()
if ext in video_extensions:
try:
result = self.__fdv.video_face_detect(media_file, self.__video_writer, output)
except:
print(traceback.format_exc())
raise
self.__video_writer.close()
elif ext in image_extensions:
result = self.image_face_detect(media_file, output)
return result
get_output_pattern
Pattern this annotation uses in an output filename.
View Source
def get_output_pattern(self):
"""Pattern this annotation uses in an output filename."""
pattern = '-face'
if self._options['portrait'] is True:
pattern = '-portrait'
return self._options.get('outputpattern', pattern)
get_input_extensions
Extensions that the annotation expects for its input filename.
Priority is given to video files, then image files.
View Source
@staticmethod
def get_input_extensions():
"""Extensions that the annotation expects for its input filename.
Priority is given to video files, then image files.
"""
out_ext = list(sppasFiles.get_informat_extensions('VIDEO'))
for img_ext in sppasFiles.get_informat_extensions('IMAGE'):
out_ext.append(img_ext)
return [out_ext]