SPPAS 4.22

https://sppas.org/

Module sppas.src.annotations

Class sppasHandPose

Description

SPPAS integration of the automatic Mediapipe Hand & Body Pose annotations.

Requires an image/video.

Constructor

Create a new sppasHandPose instance.

Parameters
  • log: (sppasLog) Human-readable logs.
View Source
def __init__(self, log=None):
    """Create a new sppasHandPose instance.

    :param log: (sppasLog) Human-readable logs.

    """
    super(sppasHandPose, self).__init__('handpose.json', log)
    self.__hdi = MediaPipeHandPoseDetector()
    self.__img_writer = sppasHandsSightsImageWriter()
    self.__hdv = VideoHandPoseDetector(self.__hdi)
    self.__video_writer = sppasSightsVideoWriter(self.__img_writer)

Public functions

load_resources

Fix the model and proto files.

Parameters
  • args
View Source
def load_resources(self, *args, **kwargs):
    """Fix the model and proto files.

        :param args:

        """
    self.__hdi.load_model()

fix_options

Fix all options.

Parameters
  • options: (sppasOption)
View Source
def fix_options(self, options):
    """Fix all options.

        :param options: (sppasOption)

        """
    for opt in options:
        key = opt.get_key()
        if key == 'hand':
            self.enable_hand(opt.get_value())
        elif key == 'pose':
            self.enable_pose(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 == 'folder':
            self.set_out_folder(opt.get_value())
        elif 'pattern' in key:
            self._options[key] = opt.get_value()
        else:
            raise AnnotationOptionError(key)

enable_hand

The result includes hand detection.

If set to False, pose detection is automatically enabled. If set to True, pose detection remains the same.

Parameters
  • value: (bool) Enable hand detection
View Source
def enable_hand(self, value=True):
    """The result includes hand detection.

        If set to False, pose detection is automatically enabled.
        If set to True, pose detection remains the same.

        :param value: (bool) Enable hand detection

        """
    v = bool(value)
    self._options['hand'] = v
    if v is False:
        self._options['pose'] = True

enable_pose

The result includes pose detection.

If set to False, hand detection is automatically enabled. If set to True, hand detection remains the same.

Parameters
  • value: (bool) Enable pose detection
View Source
def enable_pose(self, value=True):
    """The result includes pose detection.

        If set to False, hand detection is automatically enabled.
        If set to True, hand detection remains the same.

        :param value: (bool) Enable pose detection

        """
    v = bool(value)
    self._options['pose'] = v
    if v is False:
        self._options['hand'] = True

set_out_csv

The result includes a CSV file.

Parameters
  • out_csv: (bool) Create a CSV file with the coordinates
View Source
def set_out_csv(self, out_csv=False):
    """The result includes a CSV file.

        :param out_csv: (bool) Create a CSV file with the coordinates

        """
    out_csv = bool(out_csv)
    self.__video_writer.set_options(csv=out_csv)
    self._options['csv'] = out_csv
    self.__video_writer.set_options(xra=not out_csv)
    self._options['xra'] = not out_csv

set_img_tag

Draw the landmark points to the image.

Parameters
  • value: (bool) Tag the images
View Source
def set_img_tag(self, value=True):
    """Draw the landmark points to the image.

        :param value: (bool) Tag the images

        """
    value = bool(value)
    self.__img_writer.set_options(tag=value)
    self.__video_writer.set_options(tag=value)
    self._options['tag'] = 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

        """
    out_folder = bool(out_folder)
    self.__video_writer.set_options(folder=out_folder)
    self._options['folder'] = out_folder

image_hand_sights

Get the image, detect hands and write results.

Parameters
  • image_file: (str) Image filename
  • output: (str) The output name for the image
Returns
  • (list of list) the sights of all detected hands or created filenames
View Source
def image_hand_sights(self, image_file, output=None):
    """Get the image, detect hands and write results.

        :param image_file: (str) Image filename
        :param output: (str) The output name for the image

        :return: (list of list) the sights of all detected hands or created filenames

        """
    image = sppasImage(filename=image_file)
    all_hands = list()
    if self._options['hand'] is True:
        if self._options['pose'] is False:
            success = self.__hdi.detect_hands(image)
        else:
            success = self.__hdi.detect(image)
        if success is True:
            if self.logfile:
                self.logfile.print_message('{:d} hands found'.format(len(self.__hdi), indent=2, status=annots.info))
            for hand_idx in range(len(self.__hdi)):
                sights = self.__hdi.get_hand_sights(hand_idx)
                all_hands.append(sights)
        elif self.logfile:
            self.logfile.print_message('No hand found', indent=2, status=annots.info)
    if self._options['hand'] is False and self._options['pose'] is True:
        success = self.__hdi.detect_poses(image)
        if success is True:
            sights = self.__hdi.get_pose_sights()
            all_hands.append(sights)
        elif self.logfile:
            self.logfile.print_message('No hand found', indent=2, status=annots.info)
    if output is not None and len(all_hands) > 0:
        output_file = self.fix_out_file_ext(output, out_format='IMAGE')
        new_files = self.__img_writer.write(image, all_hands, output_file, pattern='')
        return new_files
    return all_hands

video_hand_sights

Get the video, detect hands and write results.

Parameters
  • video_file: (str) Video filename
  • output: (str) The output name for the video
Returns
  • (list of list) the sights of all detected hands or created filenames
View Source
def video_hand_sights(self, video_file, output=None):
    """Get the video, detect hands and write results.

        :param video_file: (str) Video filename
        :param output: (str) The output name for the video
        :return: (list of list) the sights of all detected hands or created filenames

        """
    result_files = list()
    if self._options['hand'] is True:
        if self._options['pose'] is False:
            self.__hdv.set_mode(HandPoseMode().HAND)
        else:
            self.__hdv.set_mode(HandPoseMode().BOTH)
        result_files = self.__hdv.video_hand_sights(video_file, self.__video_writer, output)
    if self._options['hand'] is False and self._options['pose'] is True:
        self.__hdv.set_mode(HandPoseMode().POSE)
        result_files = self.__hdv.video_hand_sights(video_file, self.__video_writer, output)
    return result_files

get_inputs

Return the media.

Parameters
  • input_files: (list)
Raises

NoInputError

Returns
  • (str) Names of the expected file
View Source
def get_inputs(self, input_files):
    """Return the media.

        :param input_files: (list)
        :raise: NoInputError
        :return: (str) Names of the expected file

        """
    ext = self.get_input_extensions()
    media_ext = ext[0]
    media = None
    for filename in input_files:
        _, fe = os.path.splitext(filename)
        if media is None and fe in media_ext:
            media = filename
    if media is None:
        logging.error('Neither a video nor an image was found.')
        raise NoInputError
    return media

run

Run the automatic annotation process on an input.

Parameters
  • input_files: (list of str) Input file is an image or a video
  • output: (str) the output file name
Returns
  • (list of points or filenames) detected sights of hands or created filenames
View Source
def run(self, input_files, output=None):
    """Run the automatic annotation process on an input.

        :param input_files: (list of str) Input file is an image or a video
        :param output: (str) the output file name
        :return: (list of points or filenames) detected sights of hands or created filenames

        """
    media_file = self.get_inputs(input_files)
    _, ext = os.path.splitext(media_file)
    self.__video_writer.set_image_extension(self._out_extensions['IMAGE'])
    self.__video_writer.set_video_extension(self._out_extensions['VIDEO'])
    result_files = list()
    if ext in video_extensions:
        try:
            result_files = self.video_hand_sights(media_file, output)
            self.__video_writer.close()
        except:
            import traceback
            print(traceback.format_exc())
            raise
    if ext in image_extensions:
        try:
            result_files = self.image_hand_sights(media_file, output)
        except:
            import traceback
            print(traceback.format_exc())
            raise
    return result_files

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."""
    return self._options.get('outputpattern', '-hands')

get_input_patterns

Pattern this annotation expects for its input filename.

View Source
def get_input_patterns(self):
    """Pattern this annotation expects for its input filename."""
    return [self._options.get('inputpattern1', '')]

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]