使用OpenCV、ONNXRuntime部署YOLOV7目标检测——记录贴

这两天想实现yolov5的tensort加速,小白一枚,领悟甚浅,只能记录一下,防止遗忘了。

先记录一下yolov7:

yolov7的OpenCV、ONNXRuntime部署

分享一下大佬的开源作品yolov7的OpenCV、ONNXRuntime部署
大佬不但实现了yolov7的OpenCV、ONNXRuntime部署,并且无私的贡献了转换的模型,非常感谢。

ONNXRuntime部署

基于gpu运行,速度相当快,可以做到实时。
运行步骤:下载模型文件放到yolov7-opencv-onnxrun-cpp-py-main目录下

cd yolov7-opencv-onnxrun-cpp-py-main
mikdir simples #放入几张图片和视频
#运行
python onnxruntime/main.py --imgpath simples/1.jpg --modelpath models/yolov7-tiny_384x640.onnx

结果在这里插入图片描述

增加视频流推理

在源代码基础上加上了对视频流的推理和针对某一类的推理,代码如下:

VID_FORMATS = ['asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'wmv']  # include video suffixes
imgpath = args.imgpath
    print(imgpath.split('.')[-1])
    if imgpath.split('.')[-1] in VID_FORMATS:
        cap =cv2.VideoCapture(imgpath)
        while True:
            success, srcimg = cap.read()
            srcimg = imutils.resize(srcimg, width=640)
            t1 = time.time()
            boxes, scores, class_ids = yolov7_detector.detect(srcimg)
            print(time.time() - t1)
            # Draw detections
            dstimg = yolov7_detector.draw_detections(srcimg, boxes, scores, class_ids)
            print(time.time() - t1)
            winName = 'Deep learning object detection in OpenCV'
            cv2.namedWindow(winName, 0)
            cv2.imshow(winName, dstimg)

            cv2.waitKey(1)
        cv2.destroyAllWindows()
    else:
        srcimg = cv2.imread(args.imgpath)
        # Detect Objects
        t1 = time.time()
        boxes, scores, class_ids = yolov7_detector.detect(srcimg)
        print(time.time() - t1)
        # Draw detections
        dstimg = yolov7_detector.draw_detections(srcimg, boxes, scores, class_ids)
        print(time.time() - t1)
        winName = 'Deep learning object detection in OpenCV'
        cv2.namedWindow(winName, 0)
        cv2.imshow(winName, dstimg)
        cv2.waitKey(0)
        cv2.destroyAllWindows()

修改输入源的读取方式,增加对mp4的输入支持,增加指定类的检测在代码的

 def draw_detections(self, image, boxes, scores, class_ids):
        for box, score, class_id in zip(boxes, scores, class_ids):
            x1, y1, x2, y2 = box.astype(int)
            
            # Draw rectangle
            #id对应的coconame文件的类别排序,指定识别行人
			if class_id==0:
	            cv2.rectangle(image, (x1, y1), (x2, y2), (0, 0, 255), thickness=2)
	
	            label = self.class_names[class_id]
	            label = f'{label} {int(score * 100)}%'
	            labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 1)
	            # top = max(y1, labelSize[1])
	            # cv.rectangle(frame, (left, top - round(1.5 * labelSize[1])), (left + round(1.5 * labelSize[0]), top + baseLine), (255,255,255), cv.FILLED)
	            cv2.putText(image, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), thickness=2)
        return image

结果如下
asdf

运行速度对比

均采用yolov7-tiny_384x640.onnx模型
opencv-cpu inference time:1.04 s
ONNXRuntime-gpu inference time:0.17 s


yolov5

  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
好的,下面是使用OpenCVONNXRuntime部署YOLOV7实时目标检测的代码: ```python import cv2 import numpy as np import onnxruntime as ort # 加载模型 model_path = "yolov7.onnx" session = ort.InferenceSession(model_path) # 输入、输出名 input_name = session.get_inputs()[0].name output_names = [session.get_outputs()[i].name for i in range(len(session.get_outputs()))] # 类别名称 class_names = ["person", "car", "truck", "bus"] # 预处理函数 def preprocess(image, target_shape): # 图像缩放 h, w = image.shape[:2] scale = min(target_shape[0] / h, target_shape[1] / w) new_h, new_w = int(h * scale), int(w * scale) image_resized = cv2.resize(image, (new_w, new_h)) # 图像填充 pad_h = target_shape[0] - new_h pad_w = target_shape[1] - new_w top, bottom = pad_h // 2, pad_h - pad_h // 2 left, right = pad_w // 2, pad_w - pad_w // 2 image_padded = cv2.copyMakeBorder(image_resized, top, bottom, left, right, cv2.BORDER_CONSTANT) # 图像归一化 image_scaled = image_padded / 255.0 image_normalized = (image_scaled - [0.485, 0.456, 0.406]) / [0.229, 0.224, 0.225] image_transposed = np.transpose(image_normalized, [2, 0, 1]) image_batched = np.expand_dims(image_transposed, axis=0) return image_batched # 后处理函数 def postprocess(outputs, conf_threshold, iou_threshold): # 输出解码 objects = [] for i, output in enumerate(outputs): grid_size = output.shape[2] anchor_size = 3 num_classes = output.shape[1] - 5 boxes = output.reshape([-1, 5 + num_classes]) boxes[:, 0:2] = (boxes[:, 0:2] + np.arange(grid_size).reshape([1, -1, 1])) / grid_size boxes[:, 2:4] = np.exp(boxes[:, 2:4]) * anchor_size / grid_size boxes[:, 4:] = np.exp(boxes[:, 4:]) / (1 + np.exp(-boxes[:, 4:])) boxes[:, 5:] = boxes[:, 4:5] * boxes[:, 5:] mask = boxes[:, 4] > conf_threshold boxes = boxes[mask] classes = np.argmax(boxes[:, 5:], axis=-1) scores = boxes[:, 4] * boxes[:, 5 + classes] mask = scores > conf_threshold boxes = boxes[mask] classes = classes[mask] scores = scores[mask] for cls, score, box in zip(classes, scores, boxes): if cls >= num_classes: continue x, y, w, h = box[:4] x1, y1, x2, y2 = x - w / 2, y - h / 2, x + w / 2, y + h / 2 objects.append([x1, y1, x2, y2, score, class_names[cls]]) # 非极大抑制 objects = sorted(objects, key=lambda x: x[4], reverse=True) for i in range(len(objects)): if objects[i][4] == 0: continue for j in range(i + 1, len(objects)): if iou(objects[i][:4], objects[j][:4]) > iou_threshold: objects[j][4] = 0 # 输出筛选 objects = [obj for obj in objects if obj[4] > conf_threshold] return objects # IOU计算函数 def iou(box1, box2): x1, y1, x2, y2 = box1 x3, y3, x4, y4 = box2 left = max(x1, x3) top = max(y1, y3) right = min(x2, x4) bottom = min(y2, y4) intersection = max(0, right - left) * max(0, bottom - top) area1 = (x2 - x1) * (y2 - y1) area2 = (x4 - x3) * (y4 - y3) union = area1 + area2 - intersection return intersection / (union + 1e-6) # 摄像头读取 cap = cv2.VideoCapture(0) while True: # 读取帧 ret, frame = cap.read() # 预处理 image = preprocess(frame, (416, 416)) # 推理 outputs = session.run(output_names, {input_name: image}) # 后处理 objects = postprocess(outputs, conf_threshold=0.5, iou_threshold=0.5) # 可视化 for obj in objects: x1, y1, x2, y2, score, class_name = obj cv2.rectangle(frame, (int(x1 * frame.shape[1]), int(y1 * frame.shape[0])), (int(x2 * frame.shape[1]), int(y2 * frame.shape[0])), (0, 255, 0), 2) cv2.putText(frame, class_name + ": " + str(round(score, 2)), (int(x1 * frame.shape[1]), int(y1 * frame.shape[0]) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) # 显示结果 cv2.imshow("YOLOV7", frame) # 退出 if cv2.waitKey(1) == ord("q"): break # 释放资源 cap.release() cv2.destroyAllWindows() ``` 这段代码通过摄像头实时读取视频流,对每一帧进行目标检测,并将检测结果可视化显示在窗口中。在代码中,我们首先加载了YOLOV7模型,并定义了输入、输出名和类别名称。接着,我们定义了预处理函数和后处理函数,用于对输入图像进行预处理和输出结果进行解码、筛选和可视化。最后,我们通过OpenCV读取摄像头视频流,对每一帧进行目标检测并实时显示在窗口中,直到按下“q”键退出程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一休哥※

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值