face recognition pipline adds use_det parameter to control whether to use face detection model (#1212)

* face recognition pipline adds use_det parameter to control whether to use face detection model

---------

Co-authored-by: zhaoshao <chenzhaofei.czf@alibaba-inc.com>
This commit is contained in:
chenzhaofei01
2025-03-03 14:15:36 +08:00
committed by GitHub
parent 352336a8a2
commit 51d27d7d04
3 changed files with 55 additions and 23 deletions

View File

@@ -22,7 +22,7 @@ logger = get_logger()
class FaceProcessingBasePipeline(Pipeline):
def __init__(self, model: str, **kwargs):
def __init__(self, model: str, use_det=True, **kwargs):
"""
use `model` to create a face processing pipeline and output cropped img, scores, bbox and lmks.
@@ -30,11 +30,13 @@ class FaceProcessingBasePipeline(Pipeline):
model: model id on modelscope hub.
"""
self.use_det = use_det
super().__init__(model=model, **kwargs)
# face detect pipeline
det_model_id = 'damo/cv_ddsar_face-detection_iclr23-damofd'
self.face_detection = pipeline(
Tasks.face_detection, model=det_model_id)
if use_det:
det_model_id = 'damo/cv_ddsar_face-detection_iclr23-damofd'
self.face_detection = pipeline(
Tasks.face_detection, model=det_model_id)
def _choose_face(self,
det_result,
@@ -94,21 +96,27 @@ class FaceProcessingBasePipeline(Pipeline):
def preprocess(self, input: Input) -> Dict[str, Any]:
img = LoadImage.convert_to_ndarray(input)
img = img[:, :, ::-1]
det_result = self.face_detection(img.copy())
rtn = self._choose_face(det_result, img_shape=img.shape)
if rtn is not None:
scores, bboxes, face_lmks = rtn
face_lmks = face_lmks.reshape(5, 2)
align_img, _ = align_face(img, (112, 112), face_lmks)
if self.use_det:
det_result = self.face_detection(img.copy())
rtn = self._choose_face(det_result, img_shape=img.shape)
if rtn is not None:
scores, bboxes, face_lmks = rtn
face_lmks = face_lmks.reshape(5, 2)
align_img, _ = align_face(img, (112, 112), face_lmks)
result = {}
result['img'] = np.ascontiguousarray(align_img)
result['scores'] = [scores]
result['bbox'] = bboxes
result['lmks'] = face_lmks
return result
result = {}
result['img'] = np.ascontiguousarray(align_img)
result['scores'] = [scores]
result['bbox'] = bboxes
result['lmks'] = face_lmks
return result
else:
return None
else:
return None
result = {}
resized_img = cv2.resize(img, (112, 112))
result['img'] = np.ascontiguousarray(resized_img)
return result
def align_face_padding(self, img, rect, padding_size=16, pad_pixel=127):
rect = np.reshape(rect, (-1, 4))

View File

@@ -14,10 +14,11 @@ from modelscope.outputs import OutputKeys
from modelscope.pipelines import pipeline
from modelscope.pipelines.base import Input, Pipeline
from modelscope.pipelines.builder import PIPELINES
from modelscope.pipelines.cv.face_processing_base_pipeline import \
FaceProcessingBasePipeline
from modelscope.preprocessors import LoadImage
from modelscope.utils.constant import ModelFile, Tasks
from modelscope.utils.logger import get_logger
from . import FaceProcessingBasePipeline
logger = get_logger()
@@ -26,15 +27,14 @@ logger = get_logger()
Tasks.face_recognition, module_name=Pipelines.face_recognition)
class FaceRecognitionPipeline(FaceProcessingBasePipeline):
def __init__(self, model: str, **kwargs):
def __init__(self, model: str, use_det=True, **kwargs):
"""
use `model` to create a face recognition pipeline for prediction
Args:
model: model id on modelscope hub.
"""
# face recong model
super().__init__(model=model, **kwargs)
super().__init__(model=model, use_det=use_det, **kwargs)
device = torch.device(
f'cuda:{0}' if torch.cuda.is_available() else 'cpu')
self.device = device

View File

@@ -17,8 +17,8 @@ class FaceRecognitionTest(unittest.TestCase):
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_face_compare(self):
img1 = 'data/test/images/face_recognition_1.png'
img2 = 'data/test/images/face_recognition_2.png'
img1 = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/face_recognition_1.png'
img2 = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/face_recognition_2.png'
face_recognition = pipeline(
Tasks.face_recognition, model=self.model_id)
@@ -27,6 +27,30 @@ class FaceRecognitionTest(unittest.TestCase):
sim = np.dot(emb1[0], emb2[0])
print(f'Cos similarity={sim:.3f}, img1:{img1} img2:{img2}')
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_face_compare_use_det(self):
img1 = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/face_recognition_1.png'
img2 = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/face_recognition_2.png'
face_recognition = pipeline(
Tasks.face_recognition, model=self.model_id, use_det=True)
emb1 = face_recognition(img1)[OutputKeys.IMG_EMBEDDING]
emb2 = face_recognition(img2)[OutputKeys.IMG_EMBEDDING]
sim = np.dot(emb1[0], emb2[0])
print(f'Cos similarity={sim:.3f}, img1:{img1} img2:{img2}')
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
def test_face_compare_not_use_det(self):
img1 = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/face_recognition_1.png'
img2 = 'https://modelscope.oss-cn-beijing.aliyuncs.com/test/images/face_recognition_2.png'
face_recognition = pipeline(
Tasks.face_recognition, model=self.model_id, use_det=False)
emb1 = face_recognition(img1)[OutputKeys.IMG_EMBEDDING]
emb2 = face_recognition(img2)[OutputKeys.IMG_EMBEDDING]
sim = np.dot(emb1[0], emb2[0])
print(f'Cos similarity={sim:.3f}, img1:{img1} img2:{img2}')
if __name__ == '__main__':
unittest.main()