scrfd onnx inference
fadsamo opened this issue · comments
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
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
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
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.