SPPAS integration of the automatic Mediapipe Hand & Body Pose annotations.
Requires an image/video.
SPPAS integration of the automatic Mediapipe Hand & Body Pose annotations.
Requires an image/video.
Create a new sppasHandPose instance.
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)
Fix the model and proto files.
def load_resources(self, *args, **kwargs):
"""Fix the model and proto files.
:param args:
"""
self.__hdi.load_model()
Fix all options.
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)
The result includes hand detection.
If set to False, pose detection is automatically enabled. If set to True, pose detection remains the same.
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
The result includes pose detection.
If set to False, hand detection is automatically enabled. If set to True, hand detection remains the same.
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
The result includes a CSV file.
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
Draw the landmark points to the image.
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
The result includes a folder with image files -- if video input.
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
Get the image, detect hands and write results.
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
Get the video, detect hands and write results.
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
Return the media.
NoInputError
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 the automatic annotation process on an input.
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
Pattern this annotation uses in an output filename.
def get_output_pattern(self):
"""Pattern this annotation uses in an output filename."""
return self._options.get('outputpattern', '-hands')
Pattern this annotation expects for its input filename.
def get_input_patterns(self):
"""Pattern this annotation expects for its input filename."""
return [self._options.get('inputpattern1', '')]
Extensions that the annotation expects for its input filename.
Priority is given to video files, then image files.
@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]