当前位置:   article > 正文

yolov5-face onnxruntime python推理(最简易版)_from processor import preprocess, postprocess

from processor import preprocess, postprocess

要求库:

cv2、numpy、onnxruntime

文件目录

检测图片yoloface_img.py:

  1. import cv2
  2. import numpy as np
  3. from PreProcess import PreProcess
  4. from onnx2pred import V5onnx2pred
  5. from PostProcess import PostProcess
  6. im = cv2.imread('1.jpeg')
  7. img, r, dw, dh = PreProcess().process(im)#img(640*640*3) img1(1*3*640*640)
  8. pred = np.squeeze(V5onnx2pred(p='models/yolov5s-face_1o1b.onnx').predict(img))
  9. pro = PostProcess(conf_thresh=0.3, iou_thresh=0.5)
  10. id, boxes, pred_m = pro.final(pred)
  11. for i in id:
  12. x1, y1, x2, y2 = boxes[i][:4]
  13. x1 = pro.after2before(x1, dw, r)
  14. x2 = pro.after2before(x2, dw, r)
  15. y1 = pro.after2before(y1, dh, r)
  16. y2 = pro.after2before(y2, dh, r)
  17. #eye_left
  18. elx, ely = pred_m[i][5], pred_m[i][6]
  19. elx = pro.after2before(elx, dw, r)
  20. ely = pro.after2before(ely, dh, r)
  21. # eye_right
  22. erx, ery = pred_m[i][7], pred_m[i][8]
  23. erx = pro.after2before(erx, dw, r)
  24. ery = pro.after2before(ery, dh, r)
  25. # nose
  26. nx, ny = pred_m[i][9], pred_m[i][10]
  27. nx = pro.after2before(nx, dw, r)
  28. ny = pro.after2before(ny, dh, r)
  29. # mouth_left
  30. mlx, mly = pred_m[i][11], pred_m[i][12]
  31. mlx = pro.after2before(mlx, dw, r)
  32. mly = pro.after2before(mly, dh, r)
  33. # mouth_right
  34. mrx, mry = pred_m[i][13], pred_m[i][14]
  35. mrx = pro.after2before(mrx, dw, r)
  36. mry = pro.after2before(mry, dh, r)
  37. points = [(elx, ely), (erx, ery), (nx, ny), (mlx, mly), (mrx, mry)]
  38. cv2.rectangle(im, (x1, y1), (x2, y2), (255, 192, 203), 2)
  39. cv2.circle(im, (elx, ely), 3, (255, 255, 0), -1)
  40. cv2.circle(im, (erx, ery), 3, (255, 0, 0), -1)
  41. cv2.circle(im, (nx, ny), 3, (0, 255, 0), -1)
  42. cv2.circle(im, (mlx, mly), 3, (0, 255, 255), -1)
  43. cv2.circle(im, (mrx, mry), 3, (0, 0, 255), -1)
  44. cv2.imshow('res', im)
  45. cv2.waitKey(0)
  46. cv2.destroyAllWindows()

检测视频yoloface_video.py:

  1. import cv2
  2. import numpy as np
  3. from PreProcess import PreProcess
  4. from onnx2pred import V5onnx2pred
  5. from PostProcess import PostProcess
  6. # 打开视频文件
  7. cap = cv2.VideoCapture('cht_smoke.mp4')
  8. # 读取视频的第一帧
  9. ret, frame = cap.read()
  10. if not ret:
  11. print("无法读取视频文件")
  12. exit()
  13. # 预处理第一帧并进行预测
  14. pre = PreProcess()
  15. v5 = V5onnx2pred(p='models/yolov5s-face_1o1b.onnx')
  16. post = PostProcess(conf_thresh=0.3, iou_thresh=0.5)
  17. img, r, dw, dh = pre.process(frame)
  18. pred = np.squeeze(v5.predict(img))
  19. id, boxes, pred_m = post.final(pred)
  20. # 创建一个循环来处理视频的每一帧
  21. while True:
  22. # 读取下一帧
  23. ret, frame = cap.read()
  24. if not ret:
  25. break # 如果视频结束或无法读取,则退出循环
  26. # 预处理帧并进行预测
  27. img, _, _, _ = pre.process(frame)
  28. pred = np.squeeze(v5.predict(img))
  29. # 后处理预测结果
  30. id, boxes, pred_m = post.final(pred)
  31. # 在帧上绘制结果
  32. for i in id:
  33. x1, y1, x2, y2 = boxes[i][:4]
  34. x1 = post.after2before(x1, dw, r)
  35. x2 = post.after2before(x2, dw, r)
  36. y1 = post.after2before(y1, dh, r)
  37. y2 = post.after2before(y2, dh, r)
  38. # 绘制矩形和关键点
  39. cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 192, 203), 2)
  40. # eye_left
  41. elx, ely = pred_m[i][5], pred_m[i][6]
  42. elx = post.after2before(elx, dw, r)
  43. ely = post.after2before(ely, dh, r)
  44. # eye_right
  45. erx, ery = pred_m[i][7], pred_m[i][8]
  46. erx = post.after2before(erx, dw, r)
  47. ery = post.after2before(ery, dh, r)
  48. # nose
  49. nx, ny = pred_m[i][9], pred_m[i][10]
  50. nx = post.after2before(nx, dw, r)
  51. ny = post.after2before(ny, dh, r)
  52. # mouth_left
  53. mlx, mly = pred_m[i][11], pred_m[i][12]
  54. mlx = post.after2before(mlx, dw, r)
  55. mly = post.after2before(mly, dh, r)
  56. # mouth_right
  57. mrx, mry = pred_m[i][13], pred_m[i][14]
  58. mrx = post.after2before(mrx, dw, r)
  59. mry = post.after2before(mry, dh, r)
  60. cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 192, 203), 2)
  61. cv2.circle(frame, (elx, ely), 3, (255, 255, 0), -1)
  62. cv2.circle(frame, (erx, ery), 3, (255, 0, 0), -1)
  63. cv2.circle(frame, (nx, ny), 3, (0, 255, 0), -1)
  64. cv2.circle(frame, (mlx, mly), 3, (0, 255, 255), -1)
  65. cv2.circle(frame, (mrx, mry), 3, (0, 0, 255), -1)
  66. # 显示帧
  67. cv2.imshow('Video Frame', frame)
  68. # 按'q'退出循环
  69. if cv2.waitKey(1) & 0xFF == ord('q'):
  70. break
  71. # 释放视频对象
  72. cap.release()
  73. cv2.destroyAllWindows()

预处理文件PreProcess.py

  1. # w = weight, h = height, p = path, s = scale
  2. # to(1 * 3 * 640 * 640)
  3. import cv2
  4. import numpy as np
  5. def letterbox(img, new_shape=(640, 640), color=(114, 114, 114), auto=True, scaleFill=False):
  6. shape = img.shape[:2]
  7. if isinstance(new_shape, int):
  8. new_shape = (new_shape, new_shape)
  9. r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
  10. new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
  11. dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1]
  12. if auto:
  13. dw, dh = np.mod(dw, 64), np.mod(dh, 64)
  14. elif scaleFill:
  15. dw, dh = 0.0, 0.0
  16. new_unpad = new_shape
  17. ratio = new_shape[0] / shape[1], new_shape[1] / shape[0]
  18. dw /= 2
  19. dh /= 2
  20. if shape[::-1] != new_unpad:
  21. img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
  22. top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
  23. left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
  24. img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
  25. return img, ratio, (dw, dh)
  26. class PreProcess():
  27. def __init__(self, w=640, h=640, b=1): #weight,height,batch
  28. self.w = w
  29. self.h = h
  30. self.b = b
  31. def letterbox(self, img):
  32. im = np.copy(img)
  33. shape = im.shape[:2] # current shape [height, width]
  34. new_shape = [self.w, self.h]
  35. r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
  36. new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
  37. dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding
  38. dw /= 2
  39. dh /= 2
  40. if shape[::-1] != new_unpad:
  41. im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
  42. top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
  43. left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
  44. im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(128, 128, 128))
  45. return im, r, dw, dh
  46. def img2input(self, img):
  47. img = np.transpose(img, (2,0,1))
  48. img = img/255
  49. return np.expand_dims(img, axis=0).astype(np.float32)
  50. def process(self, p):
  51. img, r, dw, dh = self.letterbox(p)
  52. img = self.img2input(img)
  53. return img, r, dw, dh

推理文件onnx2pred.py

  1. import onnxruntime
  2. class V5onnx2pred:
  3. def __init__(self, p):
  4. self.p = p
  5. def predict(self, img):
  6. session = onnxruntime.InferenceSession(self.p)
  7. input_name = session.get_inputs()[0].name
  8. label_name = session.get_outputs()[0].name
  9. pred = session.run([label_name], {input_name: img})[0]
  10. return pred
  11. class V8onnx2pred:
  12. def __init__(self, p):
  13. self.p = p
  14. def predict(self, img):
  15. session = onnxruntime.InferenceSession(self.p)
  16. input_name = session.get_inputs()[0].name
  17. label_name0 = session.get_outputs()[0].name
  18. pred0 = session.run([label_name0], {input_name: img})[0]
  19. return pred0

v8还没写好,后续更新

后处理文件PostProcess.py

  1. import numpy as np
  2. import copy
  3. class PostProcess:
  4. def __init__(self, conf_thresh=0.3, iou_thresh=0.5):
  5. self.c = conf_thresh
  6. self.i = iou_thresh
  7. def xywh2xyxy(self, boxes): # xywh坐标变为 左上 ,右下坐标 x1,y1 x2,y2
  8. xywh = copy.deepcopy(boxes[:, :4])
  9. xywh[:, 0] = boxes[:, 0] - boxes[:, 2] / 2
  10. xywh[:, 1] = boxes[:, 1] - boxes[:, 3] / 2
  11. xywh[:, 2] = boxes[:, 0] + boxes[:, 2] / 2
  12. xywh[:, 3] = boxes[:, 1] + boxes[:, 3] / 2
  13. return xywh
  14. def box_area(self, boxes):
  15. return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
  16. def box_iou(self, box1, box2):
  17. area1 = self.box_area(box1) # N
  18. area2 = self.box_area(box2) # M
  19. # broadcasting, 两个数组各维度大小 从后往前对比一致, 或者 有一维度值为1;
  20. lt = np.maximum(box1[:, np.newaxis, :2], box2[:, :2])
  21. rb = np.minimum(box1[:, np.newaxis, 2:], box2[:, 2:])
  22. wh = rb - lt
  23. wh = np.maximum(0, wh) # [N, M, 2]
  24. inter = wh[:, :, 0] * wh[:, :, 1]
  25. iou = inter / (area1[:, np.newaxis] + area2 - inter)
  26. return iou
  27. def normalpred(self, pred):
  28. pred = np.squeeze(pred)
  29. scores = pred[:, 4]
  30. mask = scores > self.c # 置信度过滤
  31. pred_m = pred[mask]
  32. boxes = self.xywh2xyxy(pred_m)
  33. scores = scores[mask]
  34. return boxes, scores, pred_m
  35. def numpy_nms(self, boxes, scores):
  36. idxs = scores.argsort() # 按分数 降序排列的索引 [N]
  37. keep = []
  38. while idxs.size > 0: # 统计数组中元素的个数
  39. max_score_index = idxs[-1]
  40. max_score_box = boxes[max_score_index][None, :]
  41. keep.append(max_score_index)
  42. if idxs.size == 1:
  43. break
  44. idxs = idxs[:-1] # 将得分最大框 从索引中删除; 剩余索引对应的框 和 得分最大框 计算IoU;
  45. other_boxes = boxes[idxs] # [?, 4]
  46. ious = self.box_iou(max_score_box, other_boxes) # 一个框和其余框比较 1XM
  47. idxs = idxs[ious[0] <= self.i]
  48. return keep
  49. def final(self, pred):
  50. boxes, scores, pred_m = self.normalpred(pred)
  51. id = self.numpy_nms(boxes, scores)
  52. return id, boxes, pred_m
  53. def after2before(self, x, d, r):
  54. return int((x - d) / r)
'
运行

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/826181
推荐阅读
相关标签
  

闽ICP备14008679号