TheEeeeLin's picture
whitening
7173af9
raw
history blame
5.47 kB
import numpy as np
import cv2
import onnxruntime
from hivision.creator.retinaface.box_utils import decode, decode_landm
from hivision.creator.retinaface.prior_box import PriorBox
def py_cpu_nms(dets, thresh):
"""Pure Python NMS baseline."""
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
scores = dets[:, 4]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
order = scores.argsort()[::-1]
keep = []
while order.size > 0:
i = order[0]
keep.append(i)
xx1 = np.maximum(x1[i], x1[order[1:]])
yy1 = np.maximum(y1[i], y1[order[1:]])
xx2 = np.minimum(x2[i], x2[order[1:]])
yy2 = np.minimum(y2[i], y2[order[1:]])
w = np.maximum(0.0, xx2 - xx1 + 1)
h = np.maximum(0.0, yy2 - yy1 + 1)
inter = w * h
ovr = inter / (areas[i] + areas[order[1:]] - inter)
inds = np.where(ovr <= thresh)[0]
order = order[inds + 1]
return keep
# 替换掉 argparse 的部分,直接使用普通变量
network = "resnet50"
use_cpu = False
confidence_threshold = 0.8
top_k = 5000
nms_threshold = 0.2
keep_top_k = 750
save_image = True
vis_thres = 0.6
ONNX_DEVICE = (
"CUDAExecutionProvider"
if onnxruntime.get_device() == "GPU"
else "CPUExecutionProvider"
)
def load_onnx_model(checkpoint_path, set_cpu=False):
providers = (
["CUDAExecutionProvider", "CPUExecutionProvider"]
if ONNX_DEVICE == "CUDAExecutionProvider"
else ["CPUExecutionProvider"]
)
if set_cpu:
sess = onnxruntime.InferenceSession(
checkpoint_path, providers=["CPUExecutionProvider"]
)
else:
try:
sess = onnxruntime.InferenceSession(checkpoint_path, providers=providers)
except Exception as e:
if ONNX_DEVICE == "CUDAExecutionProvider":
print(f"Failed to load model with CUDAExecutionProvider: {e}")
print("Falling back to CPUExecutionProvider")
# 尝试使用CPU加载模型
sess = onnxruntime.InferenceSession(
checkpoint_path, providers=["CPUExecutionProvider"]
)
else:
raise e # 如果是CPU执行失败,重新抛出异常
return sess
def retinaface_detect_faces(image, model_path: str, sess=None):
cfg = {
"name": "Resnet50",
"min_sizes": [[16, 32], [64, 128], [256, 512]],
"steps": [8, 16, 32],
"variance": [0.1, 0.2],
"clip": False,
"loc_weight": 2.0,
"gpu_train": True,
"batch_size": 24,
"ngpu": 4,
"epoch": 100,
"decay1": 70,
"decay2": 90,
"image_size": 840,
"pretrain": True,
"return_layers": {"layer2": 1, "layer3": 2, "layer4": 3},
"in_channel": 256,
"out_channel": 256,
}
# Load ONNX model
if sess is None:
retinaface = load_onnx_model(model_path, set_cpu=False)
else:
retinaface = sess
resize = 1
# Read and preprocess the image
img_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
img = np.float32(img_rgb)
im_height, im_width, _ = img.shape
scale = np.array([img.shape[1], img.shape[0], img.shape[1], img.shape[0]])
img -= (104, 117, 123)
img = img.transpose(2, 0, 1)
img = np.expand_dims(img, axis=0)
# Run the model
inputs = {"input": img}
loc, conf, landms = retinaface.run(None, inputs)
priorbox = PriorBox(cfg, image_size=(im_height, im_width))
priors = priorbox.forward()
prior_data = priors
boxes = decode(np.squeeze(loc, axis=0), prior_data, cfg["variance"])
boxes = boxes * scale / resize
scores = np.squeeze(conf, axis=0)[:, 1]
landms = decode_landm(np.squeeze(landms.data, axis=0), prior_data, cfg["variance"])
scale1 = np.array(
[
img.shape[3],
img.shape[2],
img.shape[3],
img.shape[2],
img.shape[3],
img.shape[2],
img.shape[3],
img.shape[2],
img.shape[3],
img.shape[2],
]
)
landms = landms * scale1 / resize
# ignore low scores
inds = np.where(scores > confidence_threshold)[0]
boxes = boxes[inds]
landms = landms[inds]
scores = scores[inds]
# keep top-K before NMS
order = scores.argsort()[::-1][:top_k]
boxes = boxes[order]
landms = landms[order]
scores = scores[order]
# do NMS
dets = np.hstack((boxes, scores[:, np.newaxis])).astype(np.float32, copy=False)
keep = py_cpu_nms(dets, nms_threshold)
dets = dets[keep, :]
landms = landms[keep]
# keep top-K faster NMS
dets = dets[:keep_top_k, :]
landms = landms[:keep_top_k, :]
dets = np.concatenate((dets, landms), axis=1)
return dets, retinaface
if __name__ == "__main__":
import gradio as gr
# Create Gradio interface
iface = gr.Interface(
fn=retinaface_detect_faces,
inputs=[
gr.Image(
type="numpy", label="上传图片", height=400
), # Set the height to 400
gr.Textbox(value="./FaceDetector.onnx", label="ONNX模型路径"),
],
outputs=gr.Number(label="检测到的人脸数量"),
title="人脸检测",
description="上传图片并提供ONNX模型路径以检测人脸数量。",
)
# Launch the Gradio app
iface.launch()