1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
| import time
import cv2 import numpy as np import onnxruntime as ort
class ONNXObjectDetector: def __init__(self, image_path): """ 初始化 ONNX 目标检测器 - 加载 ONNX 模型 - 设置类别名称、输入尺寸、置信度阈值等参数 """ self.image_path = image_path self.model_path = '../best3.onnx' self.class_names = ["text"] self.input_size = (512, 512) self.conf_threshold = 0.5 self.nms_threshold = 0.45 self.colors = np.random.uniform(0, 255, size=(len(self.class_names), 3)) self.session = ort.InferenceSession(self.model_path)
def preprocess_image(self): """ 预处理输入图像,使其适配模型输入要求 :return: 预处理后的图像、原始图像和缩放比例 """ original_image = cv2.imread(self.image_path) height, width, _ = original_image.shape length = max(self.input_size) image = np.zeros((length, length, 3), np.uint8) image[0:height, 0:width] = original_image
scale = length / self.input_size[0] blob = cv2.dnn.blobFromImage(image, scalefactor=1 / 255.0, size=self.input_size, swapRB=True) return blob, original_image, scale
def detect_objects(self): """ 执行目标检测 :return: 检测结果列表 """ blob, original_image, scale = self.preprocess_image() input_name = self.session.get_inputs()[0].name outputs = self.session.run(None, {input_name: blob}) outputs = np.array([cv2.transpose(outputs[0][0])])
rows = outputs.shape[1] boxes, scores, class_ids = [], [], []
for i in range(rows): class_scores = outputs[0][i][4:] _, max_score, _, (x, max_class_idx) = cv2.minMaxLoc(class_scores) if max_score >= self.conf_threshold: box = [ outputs[0][i][0] - (0.5 * outputs[0][i][2]), outputs[0][i][1] - (0.5 * outputs[0][i][3]), outputs[0][i][2], outputs[0][i][3], ] boxes.append(box) scores.append(max_score) class_ids.append(max_class_idx) result_indices = cv2.dnn.NMSBoxes(boxes, scores, self.conf_threshold, self.nms_threshold) detections = [] if len(result_indices) > 0: for i in result_indices.flatten(): box = boxes[i] detection = { "class_id": class_ids[i], "class_name": self.class_names[class_ids[i]], "confidence": scores[i], "box": [ round(box[0] * scale), round(box[1] * scale), round((box[0] + box[2]) * scale), round((box[1] + box[3]) * scale), ], } detections.append(detection)
return detections, original_image
def draw_detections(self, image, detections): """ 在图像上绘制检测结果 :param image: 原始图像 :param detections: 检测结果列表 """ for detection in detections: x1, y1, x2, y2 = detection["box"] class_id = detection["class_id"] color = self.colors[class_id] label = f"{detection['class_name']} ({detection['confidence']:.2f})"
cv2.rectangle(image, (x1, y1), (x2, y2), color, 2) cv2.putText(image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
cv2.imshow("Detections", image) cv2.waitKey(0) cv2.destroyAllWindows()
if __name__ == "__main__": start = time.time() image_path = r"test.jpg"
detector = ONNXObjectDetector(image_path) detections, processed_image = detector.detect_objects() end = time.time() print(end - start) if detections: print("检测结果:") for det in detections: print(f"类别: {det['class_name']}, 置信度: {det['confidence']:.2f}, 坐标: {det['box']}") detector.draw_detections(processed_image, detections) else: print("检测失败,数据集不足或该照片中无目标")
|