1、下载yolov9的项目
地址:YOLOv9
2、使用下面代码进行检测
import torch
import cv2
from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_boxes
from utils.plots import plot_one_box
# 加载预训练的YOLOv9模型
model = attempt_load(r'./yolov9-t-converted.pt', device='cpu') # 使用CPU进行推理,如果有GPU可以切换到'cuda'
# 获取摄像头内容,参数 0 表示使用默认的摄像头
cap = cv2.VideoCapture(0,cv2.CAP_DSHOW)
# 打开视频文件
# cap = cv2.VideoCapture('video.mp4')
# 获取视频的宽度和高度
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 定义视频写入对象
out = cv2.VideoWriter('output.avi', cv2.VideoWriter_fourcc(*'XVID'), 30, (frame_width, frame_height))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 转换为RGB格式并进行检测
img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img_tensor = torch.from_numpy(img).to('cpu').permute(2, 0, 1).float() / 255.0 # 转换为Tensor并归一化
img_tensor = img_tensor.unsqueeze(0)
# 推理
results = model(img_tensor)[0]
# 后处理:非极大值抑制
results = non_max_suppression(results, 0.4, 0.5)
# 绘制检测框
for det in results:
if det is not None and len(det):
det[:, :4] = scale_boxes(img_tensor.shape[2:], det[:, :4], frame.shape).round()
for *xyxy, conf, cls in det:
label = f'{model.names[int(cls)]} {conf:.2f}'
plot_one_box(xyxy, frame, label=label, color=(255, 0, 0), line_thickness=2)
# 写入视频文件
out.write(frame)
# 显示结果
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
out.release()
cv2.destroyAllWindows()
3、在from utils.plots中添加plot_one_box
源码没有这个函数,直接在plots里面添加一个新的plot_one_box
方法。否则会报错
def plot_one_box(x, img, color=None, label=None, line_thickness=None):
# Plots one bounding box on image img
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 # line/font thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA) # filled
cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)