Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scrfd onnx inference #101

Open
fadsamo opened this issue Nov 8, 2022 · 4 comments
Open

scrfd onnx inference #101

fadsamo opened this issue Nov 8, 2022 · 4 comments

Comments

@fadsamo
Copy link

fadsamo commented Nov 8, 2022

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
Copy link
Owner

SthPhoenix commented Nov 9, 2022

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
Copy link
Author

fadsamo commented Nov 10, 2022

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
Copy link
Owner

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
Copy link

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants