Browse Source

[to #42322933]add face 2d keypoints by EasyCV

Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/9934673

    * add face 2d keypoints
master
shouzhou.bx yingda.chen 3 years ago
parent
commit
4073376f51
14 changed files with 175 additions and 7 deletions
  1. +3
    -0
      data/test/images/keypoints_detect/test_img_face_2d_keypoints.png
  2. +3
    -0
      modelscope/metainfo.py
  3. +3
    -3
      modelscope/models/cv/__init__.py
  4. +20
    -0
      modelscope/models/cv/face_2d_keypoints/__init__.py
  5. +16
    -0
      modelscope/models/cv/face_2d_keypoints/face_2d_keypoints_align.py
  6. +20
    -0
      modelscope/msdatasets/cv/face_2d_keypoins/__init__.py
  7. +13
    -0
      modelscope/msdatasets/cv/face_2d_keypoins/face_2d_keypoints_dataset.py
  8. +9
    -0
      modelscope/outputs.py
  9. +2
    -0
      modelscope/pipelines/builder.py
  10. +5
    -3
      modelscope/pipelines/cv/__init__.py
  11. +3
    -1
      modelscope/pipelines/cv/easycv_pipelines/__init__.py
  12. +41
    -0
      modelscope/pipelines/cv/easycv_pipelines/face_2d_keypoints_pipeline.py
  13. +1
    -0
      modelscope/utils/constant.py
  14. +36
    -0
      tests/pipelines/test_face_2d_keypoints.py

+ 3
- 0
data/test/images/keypoints_detect/test_img_face_2d_keypoints.png View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:331ead75033fa2f01f6be72a2f8e34d581fcb593308067815d4bb136bb13b766
size 54390

+ 3
- 0
modelscope/metainfo.py View File

@@ -24,6 +24,7 @@ class Models(object):
body_2d_keypoints = 'body-2d-keypoints'
body_3d_keypoints = 'body-3d-keypoints'
crowd_counting = 'HRNetCrowdCounting'
face_2d_keypoints = 'face-2d-keypoints'
panoptic_segmentation = 'swinL-panoptic-segmentation'
image_reid_person = 'passvitb'
video_summarization = 'pgl-video-summarization'
@@ -112,6 +113,7 @@ class Pipelines(object):
object_detection = 'vit-object-detection'
easycv_detection = 'easycv-detection'
easycv_segmentation = 'easycv-segmentation'
face_2d_keypoints = 'mobilenet_face-2d-keypoints_alignment'
salient_detection = 'u2net-salient-detection'
image_classification = 'image-classification'
face_detection = 'resnet-face-detection-scrfd10gkps'
@@ -353,6 +355,7 @@ class Datasets(object):
""" Names for different datasets.
"""
ClsDataset = 'ClsDataset'
Face2dKeypointsDataset = 'Face2dKeypointsDataset'
SegDataset = 'SegDataset'
DetDataset = 'DetDataset'
DetImagesMixDataset = 'DetImagesMixDataset'

+ 3
- 3
modelscope/models/cv/__init__.py View File

@@ -3,9 +3,9 @@
# yapf: disable
from . import (action_recognition, animal_recognition, body_2d_keypoints,
body_3d_keypoints, cartoon, cmdssl_video_embedding,
crowd_counting, face_detection, face_generation,
image_classification, image_color_enhance, image_colorization,
image_denoise, image_instance_segmentation,
crowd_counting, face_2d_keypoints, face_detection,
face_generation, image_classification, image_color_enhance,
image_colorization, image_denoise, image_instance_segmentation,
image_panoptic_segmentation, image_portrait_enhancement,
image_reid_person, image_semantic_segmentation,
image_to_image_generation, image_to_image_translation,


+ 20
- 0
modelscope/models/cv/face_2d_keypoints/__init__.py View File

@@ -0,0 +1,20 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from typing import TYPE_CHECKING

from modelscope.utils.import_utils import LazyImportModule

if TYPE_CHECKING:
from .face_2d_keypoints_align import Face2DKeypoints

else:
_import_structure = {'face_2d_keypoints_align': ['Face2DKeypoints']}

import sys

sys.modules[__name__] = LazyImportModule(
__name__,
globals()['__file__'],
_import_structure,
module_spec=__spec__,
extra_objects={},
)

+ 16
- 0
modelscope/models/cv/face_2d_keypoints/face_2d_keypoints_align.py View File

@@ -0,0 +1,16 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from easycv.models.face.face_keypoint import FaceKeypoint

from modelscope.metainfo import Models
from modelscope.models.builder import MODELS
from modelscope.models.cv.easycv_base import EasyCVBaseModel
from modelscope.utils.constant import Tasks


@MODELS.register_module(
group_key=Tasks.face_2d_keypoints, module_name=Models.face_2d_keypoints)
class Face2DKeypoints(EasyCVBaseModel, FaceKeypoint):

def __init__(self, model_dir=None, *args, **kwargs):
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
FaceKeypoint.__init__(self, *args, **kwargs)

+ 20
- 0
modelscope/msdatasets/cv/face_2d_keypoins/__init__.py View File

@@ -0,0 +1,20 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from typing import TYPE_CHECKING

from modelscope.utils.import_utils import LazyImportModule

if TYPE_CHECKING:
from .face_2d_keypoints_dataset import FaceKeypointDataset

else:
_import_structure = {'face_2d_keypoints_dataset': ['FaceKeypointDataset']}

import sys

sys.modules[__name__] = LazyImportModule(
__name__,
globals()['__file__'],
_import_structure,
module_spec=__spec__,
extra_objects={},
)

+ 13
- 0
modelscope/msdatasets/cv/face_2d_keypoins/face_2d_keypoints_dataset.py View File

@@ -0,0 +1,13 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from easycv.datasets.face import FaceKeypointDataset as _FaceKeypointDataset

from modelscope.metainfo import Datasets
from modelscope.msdatasets.task_datasets.builder import TASK_DATASETS
from modelscope.utils.constant import Tasks


@TASK_DATASETS.register_module(
group_key=Tasks.face_2d_keypoints,
module_name=Datasets.Face2dKeypointsDataset)
class FaceKeypointDataset(_FaceKeypointDataset):
"""EasyCV dataset for face 2d keypoints."""

+ 9
- 0
modelscope/outputs.py View File

@@ -57,6 +57,15 @@ TASK_OUTPUTS = {
# }
Tasks.ocr_recognition: [OutputKeys.TEXT],

# face 2d keypoint result for single sample
# {
# "keypoints": [
# [x1, y1]*106
# ],
# "poses": [pitch, roll, yaw]
# }
Tasks.face_2d_keypoints: [OutputKeys.KEYPOINTS, OutputKeys.POSES],

# face detection result for single sample
# {
# "scores": [0.9, 0.1, 0.05, 0.05]


+ 2
- 0
modelscope/pipelines/builder.py View File

@@ -103,6 +103,8 @@ DEFAULT_MODEL_FOR_PIPELINE = {
'damo/cv_resnet_facedetection_scrfd10gkps'),
Tasks.face_recognition: (Pipelines.face_recognition,
'damo/cv_ir101_facerecognition_cfglint'),
Tasks.face_2d_keypoints: (Pipelines.face_2d_keypoints,
'damo/cv_mobilenet_face-2d-keypoints_alignment'),
Tasks.video_multi_modal_embedding:
(Pipelines.video_multi_modal_embedding,
'damo/multi_modal_clip_vtretrival_msrvtt_53'),


+ 5
- 3
modelscope/pipelines/cv/__init__.py View File

@@ -43,7 +43,7 @@ if TYPE_CHECKING:
from .tinynas_classification_pipeline import TinynasClassificationPipeline
from .video_category_pipeline import VideoCategoryPipeline
from .virtual_try_on_pipeline import VirtualTryonPipeline
from .easycv_pipelines import EasyCVDetectionPipeline, EasyCVSegmentationPipeline
from .easycv_pipelines import EasyCVDetectionPipeline, EasyCVSegmentationPipeline, Face2DKeypointsPipeline
from .text_driven_segmentation_pipleline import TextDrivenSegmentationPipleline
from .movie_scene_segmentation_pipeline import MovieSceneSegmentationPipeline

@@ -96,8 +96,10 @@ else:
'tinynas_classification_pipeline': ['TinynasClassificationPipeline'],
'video_category_pipeline': ['VideoCategoryPipeline'],
'virtual_try_on_pipeline': ['VirtualTryonPipeline'],
'easycv_pipeline':
['EasyCVDetectionPipeline', 'EasyCVSegmentationPipeline'],
'easycv_pipeline': [
'EasyCVDetectionPipeline', 'EasyCVSegmentationPipeline',
'Face2DKeypointsPipeline'
],
'text_driven_segmentation_pipeline':
['TextDrivenSegmentationPipeline'],
'movie_scene_segmentation_pipeline':


+ 3
- 1
modelscope/pipelines/cv/easycv_pipelines/__init__.py View File

@@ -6,10 +6,12 @@ from modelscope.utils.import_utils import LazyImportModule
if TYPE_CHECKING:
from .detection_pipeline import EasyCVDetectionPipeline
from .segmentation_pipeline import EasyCVSegmentationPipeline
from .face_2d_keypoints_pipeline import Face2DKeypointsPipeline
else:
_import_structure = {
'detection_pipeline': ['EasyCVDetectionPipeline'],
'segmentation_pipeline': ['EasyCVSegmentationPipeline']
'segmentation_pipeline': ['EasyCVSegmentationPipeline'],
'face_2d_keypoints_pipeline': ['Face2DKeypointsPipeline']
}

import sys


+ 41
- 0
modelscope/pipelines/cv/easycv_pipelines/face_2d_keypoints_pipeline.py View File

@@ -0,0 +1,41 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from typing import Any

from modelscope.metainfo import Pipelines
from modelscope.outputs import OutputKeys
from modelscope.pipelines.builder import PIPELINES
from modelscope.preprocessors import LoadImage
from modelscope.utils.constant import ModelFile, Tasks
from .base import EasyCVPipeline


@PIPELINES.register_module(
Tasks.face_2d_keypoints, module_name=Pipelines.face_2d_keypoints)
class Face2DKeypointsPipeline(EasyCVPipeline):
"""Pipeline for face 2d keypoints detection."""

def __init__(self,
model: str,
model_file_pattern=ModelFile.TORCH_MODEL_FILE,
*args,
**kwargs):
"""
model (str): model id on modelscope hub or local model path.
model_file_pattern (str): model file pattern.
"""

super(Face2DKeypointsPipeline, self).__init__(
model=model,
model_file_pattern=model_file_pattern,
*args,
**kwargs)

def show_result(self, img, points, scale=2, save_path=None):
return self.predict_op.show_result(img, points, scale, save_path)

def __call__(self, inputs) -> Any:
output = self.predict_op(inputs)[0][0]
points = output['point']
poses = output['pose']

return {OutputKeys.KEYPOINTS: points, OutputKeys.POSES: poses}

+ 1
- 0
modelscope/utils/constant.py View File

@@ -20,6 +20,7 @@ class CVTasks(object):
animal_recognition = 'animal-recognition'
face_detection = 'face-detection'
face_recognition = 'face-recognition'
face_2d_keypoints = 'face-2d-keypoints'
human_detection = 'human-detection'
human_object_interaction = 'human-object-interaction'
face_image_generation = 'face-image-generation'


+ 36
- 0
tests/pipelines/test_face_2d_keypoints.py View File

@@ -0,0 +1,36 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
import unittest

import cv2

from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
from modelscope.utils.test_utils import test_level


class EasyCVFace2DKeypointsPipelineTest(unittest.TestCase):

@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_face_2d_keypoints(self):
img_path = 'data/test/images/keypoints_detect/test_img_face_2d_keypoints.png'
model_id = 'damo/cv_mobilenet_face-2d-keypoints_alignment'

face_2d_keypoints_align = pipeline(
task=Tasks.face_2d_keypoints, model=model_id)
output = face_2d_keypoints_align(img_path)

output_keypoints = output[OutputKeys.KEYPOINTS]
output_pose = output[OutputKeys.POSES]

img = cv2.imread(img_path)
img = face_2d_keypoints_align.show_result(
img, output_keypoints, scale=2, save_path='face_keypoints.jpg')

self.assertEqual(output_keypoints.shape[0], 106)
self.assertEqual(output_keypoints.shape[1], 2)
self.assertEqual(output_pose.shape[0], 3)


if __name__ == '__main__':
unittest.main()

Loading…
Cancel
Save