From 51d27d7d04224931e0545fb2116f1ef81c1cc015 Mon Sep 17 00:00:00 2001 From: chenzhaofei01 <115684391+chenzhaofei01@users.noreply.github.com> Date: Mon, 3 Mar 2025 14:15:36 +0800 Subject: [PATCH] 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 --- .../cv/face_processing_base_pipeline.py | 42 +++++++++++-------- .../pipelines/cv/face_recognition_pipeline.py | 8 ++-- tests/pipelines/test_face_recognition.py | 28 ++++++++++++- 3 files changed, 55 insertions(+), 23 deletions(-) diff --git a/modelscope/pipelines/cv/face_processing_base_pipeline.py b/modelscope/pipelines/cv/face_processing_base_pipeline.py index b9b81c9c..b2c376ca 100644 --- a/modelscope/pipelines/cv/face_processing_base_pipeline.py +++ b/modelscope/pipelines/cv/face_processing_base_pipeline.py @@ -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)) diff --git a/modelscope/pipelines/cv/face_recognition_pipeline.py b/modelscope/pipelines/cv/face_recognition_pipeline.py index 4af5a04f..8f595aef 100644 --- a/modelscope/pipelines/cv/face_recognition_pipeline.py +++ b/modelscope/pipelines/cv/face_recognition_pipeline.py @@ -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 diff --git a/tests/pipelines/test_face_recognition.py b/tests/pipelines/test_face_recognition.py index 7b84590c..bdbdb849 100644 --- a/tests/pipelines/test_face_recognition.py +++ b/tests/pipelines/test_face_recognition.py @@ -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()