[TIL] Insightface 사용 해보기

김연찬·2024년 9월 22일

준비

[TIL] Mediapipe 모델 실행 해보기

준비 단계 참조. 단, 6번 단계만 다르다.

  1. insightface를 설치한다.
    pip install insightface
  2. onnxruntime을 설치한다.
    pip install onnxruntime
  3. ImportError: cannot import name 'preserve_channel_dim' from 'albucore.utils' 오류 발생시
    pip install albucore==0.0.16
  4. AttributeError: module 'numpy' has no attribute 'int'. 오류 발생시 face_analysis.py 파일에서 84번째 줄, 88번째 줄의 int -> int_로 수정해준다. int은 더 이상 사용하지 않기 때문에 발생하는 오류이다.
# -*- coding: utf-8 -*-
# @Organization  : insightface.ai
# @Author        : Jia Guo
# @Time          : 2021-05-04
# @Function      : 


from __future__ import division

import glob
import os.path as osp

import numpy as np
import onnxruntime
from numpy.linalg import norm

from ..model_zoo import model_zoo
from ..utils import DEFAULT_MP_NAME, ensure_available
from .common import Face

__all__ = ['FaceAnalysis']

class FaceAnalysis:
    def __init__(self, name=DEFAULT_MP_NAME, root='~/.insightface', allowed_modules=None, **kwargs):
        onnxruntime.set_default_logger_severity(3)
        self.models = {}
        self.model_dir = ensure_available('models', name, root=root)
        onnx_files = glob.glob(osp.join(self.model_dir, '*.onnx'))
        onnx_files = sorted(onnx_files)
        for onnx_file in onnx_files:
            model = model_zoo.get_model(onnx_file, **kwargs)
            if model is None:
                print('model not recognized:', onnx_file)
            elif allowed_modules is not None and model.taskname not in allowed_modules:
                print('model ignore:', onnx_file, model.taskname)
                del model
            elif model.taskname not in self.models and (allowed_modules is None or model.taskname in allowed_modules):
                print('find model:', onnx_file, model.taskname, model.input_shape, model.input_mean, model.input_std)
                self.models[model.taskname] = model
            else:
                print('duplicated model task type, ignore:', onnx_file, model.taskname)
                del model
        assert 'detection' in self.models
        self.det_model = self.models['detection']


    def prepare(self, ctx_id, det_thresh=0.5, det_size=(640, 640)):
        self.det_thresh = det_thresh
        assert det_size is not None
        print('set det-size:', det_size)
        self.det_size = det_size
        for taskname, model in self.models.items():
            if taskname=='detection':
                model.prepare(ctx_id, input_size=det_size, det_thresh=det_thresh)
            else:
                model.prepare(ctx_id)

    def get(self, img, max_num=0):
        bboxes, kpss = self.det_model.detect(img,
                                             max_num=max_num,
                                             metric='default')
        if bboxes.shape[0] == 0:
            return []
        ret = []
        for i in range(bboxes.shape[0]):
            bbox = bboxes[i, 0:4]
            det_score = bboxes[i, 4]
            kps = None
            if kpss is not None:
                kps = kpss[i]
            face = Face(bbox=bbox, kps=kps, det_score=det_score)
            for taskname, model in self.models.items():
                if taskname=='detection':
                    continue
                model.get(img, face)
            ret.append(face)
        return ret

    def draw_on(self, img, faces):
        import cv2
        dimg = img.copy()
        for i in range(len(faces)):
            face = faces[i]
            # int -> int_
            box = face.bbox.astype(np.int_) 
            color = (0, 0, 255)
            cv2.rectangle(dimg, (box[0], box[1]), (box[2], box[3]), color, 2)
            if face.kps is not None:
                # int -> int_
                kps = face.kps.astype(np.int_)
                #print(landmark.shape)
                for l in range(kps.shape[0]):
                    color = (0, 0, 255)
                    if l == 0 or l == 3:
                        color = (0, 255, 0)
                    cv2.circle(dimg, (kps[l][0], kps[l][1]), 1, color,
                               2)
            if face.gender is not None and face.age is not None:
                cv2.putText(dimg,'%s,%d'%(face.sex,face.age), (box[0]-1, box[1]-4),cv2.FONT_HERSHEY_COMPLEX,0.7,(0,255,0),1)

            #for key, value in face.items():
            #    if key.startswith('landmark_3d'):
            #        print(key, value.shape)
            #        print(value[0:10,:])
            #        lmk = np.round(value).astype(np.int)
            #        for l in range(lmk.shape[0]):
            #            color = (255, 0, 0)
            #            cv2.circle(dimg, (lmk[l][0], lmk[l][1]), 1, color,
            #                       2)
        return dimg

실행

# STEP 1. import modules
import cv2
import sys
import numpy as np
import insightface
from insightface.app import FaceAnalysis
from insightface.data import get_image as ins_get_image

assert insightface.__version__>='0.3'

# STEP 2. make inference instance
app = FaceAnalysis()
app.prepare(ctx_id=0, det_size=(640, 640))

# STEP 3. load input data
img1 = cv2.imread("fake-1.jpg")
img2 = cv2.imread("true-1.jpg")

# STEP 4. inference
faces1 = app.get(img1)
faces2 = app.get(img2)

assert len(faces1)==1
assert len(faces2)==1

# STEP 5. post processing
face1 = faces1[0]
face2 = faces2[0]

# Get embedding from face
face1_emb = face1.normed_embedding
face2_emb = face2.normed_embedding

# convert numpy array from primitive array
face1_emb = np.array(face1_emb, dtype=np.float32)
face2_emb = np.array(face2_emb, dtype=np.float32)

sims = np.dot(face1_emb, face2_emb.T)
print(sims)

0개의 댓글