SthPhoenix / InsightFace-REST

InsightFace REST API for easy deployment of face recognition services with TensorRT in Docker.
Apache License 2.0
501 stars 117 forks source link

scrfd onnx inference #101

Open fadsamo opened 2 years ago

fadsamo commented 2 years ago

Hello, thank you for this valuable work you have done. I want to use the scrfd module alone and my code is as follows, but I get an error.


from scrfd import SCRFD
from face_detectors import scrfd
import onnx
import cv2
from configs import Configs 
onnx_batch_size=1
height,width=[640,640]
model = onnx.load("./models/onnx/scrfd_500m_gnkps/scrfd_500m_gnkps.onnx")
reshaped = reshape(model,n = onnx_batch_size,h = height,w=width)
onnx_model = reshaped.SerializedToString()
config = Configs(models_dir='./models/onnx/scrfd_500m_gnkps/')
outputs = config.get_outputs_order('"scrfd_500m_gnkps")
detector = scrfd(onnx_model, onnx_backend,outputs)
detector.prepare()
img = cv2.imread('1.jpg')
data = cv2.resize(img,(640,640))
bboxes ,landmarks = detector.detect(data,threshold=0.3)

but i have this error:

np.zeros(tuple(self.input.shape[1:]),self.input_dtype)]})
TypeError: 'str' object cannot be interpreted as an integer
SthPhoenix commented 2 years ago

Hi! Hope this extended example would help you:

import cv2
from modules.model_zoo.getter import get_model
from modules.imagedata import resize_image

def draw_faces(image, bboxes, landmarks, scores, draw_landmarks=True, draw_scores=True, draw_sizes=True):
    for i, bbox in enumerate(bboxes):
        pt1 = tuple(bbox[0:2].astype(int))
        pt2 = tuple(bbox[2:4].astype(int))
        color = (0, 255, 0)
        x, y = pt1
        r, b = pt2
        w = r - x

        cv2.rectangle(image, pt1, pt2, color, 1)

        if draw_landmarks:
            lms = landmarks[i].astype(int)
            pt_size = int(w * 0.05)
            cv2.circle(image, (lms[0][0], lms[0][1]), 1, (0, 0, 255), pt_size)
            cv2.circle(image, (lms[1][0], lms[1][1]), 1, (0, 255, 255), pt_size)
            cv2.circle(image, (lms[2][0], lms[2][1]), 1, (255, 0, 255), pt_size)
            cv2.circle(image, (lms[3][0], lms[3][1]), 1, (0, 255, 0), pt_size)
            cv2.circle(image, (lms[4][0], lms[4][1]), 1, (255, 0, 0), pt_size)

        if draw_scores:
            text = f"{scores[i]:.3f}"
            pos = (x + 3, y - 5)
            textcolor = (0, 0, 0)
            thickness = 1
            border = int(thickness / 2)
            cv2.rectangle(image, (x - border, y - 21, w + thickness, 21), color, -1, 16)
            cv2.putText(image, text, pos, 0, 0.5, color, 3, 16)
            cv2.putText(image, text, pos, 0, 0.5, textcolor, 1, 16)

        if draw_sizes:
            text = f"w:{w}"
            pos = (x + 3, b - 5)
            cv2.putText(image, text, pos, 0, 0.5, (0, 0, 0), 3, 16)
            cv2.putText(image, text, pos, 0, 0.5, (0, 255, 0), 1, 16)

    total = f'faces: {len(bboxes)}'
    bottom = image.shape[0]
    cv2.putText(image, total, (5, bottom - 5), 0, 1, (0, 0, 0), 3, 16)
    cv2.putText(image, total, (5, bottom - 5), 0, 1, (0, 255, 0), 1, 16)

    return image

# Translate bboxes and landmarks from resized to original image size
def reproject_points(dets, scale: float):
    if scale != 1.0:
        dets = dets / scale
    return dets

if __name__ == "__main__":
    # Load and prepare detector
    detect_size = [640, 640]
    model_name = 'scrfd_500m_gnkps'
    detector = get_model(model_name=model_name, backend_name='onnx', im_size=detect_size)
    detector.prepare()

    # Read and resize image
    image = cv2.imread('test_images/lumia.jpg')
    res_image, scale_factor = resize_image(image, detect_size)

    # Run detection on resized image
    bboxes, landmarks = detector.detect([res_image])

    # Scale detected boxes and points to coordinates of original image
    boxes = reproject_points(bboxes[0][:, :4], scale=scale_factor)
    lms = reproject_points(landmarks[0], scale=scale_factor)
    scores = bboxes[0][:, 4]

    # Draw detections on original, not resized image
    out_image = draw_faces(image, boxes, lms, scores)

    cv2.imwrite(f'{model_name}.jpg', out_image)

This script should be run inside src/api_trt directory

fadsamo commented 2 years ago

Thank you very much. The problem was solved. I'm just wondering how to get the output for the feature extraction? I want to use w600k_r50.onnx model and get output. It means that I can align the output of this detection (fast align) and give it to the function for feature extraction.

face detection >> face alignment >> feature extraction

SthPhoenix commented 1 year ago

Hi! For full pipeline you can refer to api_trt/modules/face_model.py, its get() method accepts list of images and runs full face detection >> face alignment >> feature extraction pipeline.

kuanyshbakytuly commented 6 months ago

How do you get ./models/onnx/scrfd_500m_gnkps/scrfd_500m_gnkps.onnx ? From insightface?

Converting scrfd_500m_gnkps.pth to onnx using tools/scrfd2onnx.py? Am I right?