给我写一个目标检测的python程序,基于Pytorch框架,使用yolov5算法,可以检测视频,也可以调用摄像头,并打印每一帧图片识别出来的物体
时间: 2024-06-08 13:12:27 浏览: 120
好的,下面是一个基于PyTorch和YOLOv5的目标检测程序,可以检测视频和调用摄像头,并打印每一帧图片识别出来的物体。请确保已经安装好了PyTorch和YOLOv5。
```python
import torch
import cv2
import argparse
from pathlib import Path
# 导入YOLOv5模型
from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_coords
from utils.datasets import LoadStreams, LoadImages
from utils.torch_utils import select_device
# 使用命令行参数指定视频文件或摄像头
parser = argparse.ArgumentParser()
parser.add_argument('--source', type=str, default='0', help='source') # file/folder, 0 for webcam
args = parser.parse_args()
# 初始化模型和设备
weights = 'yolov5s.pt'
device = select_device('')
model = attempt_load(weights, map_location=device) # load FP32 model
model.eval()
# 定义类别名称
names = model.module.names if hasattr(model, 'module') else model.names
# 打开视频流或摄像头
if args.source.isnumeric():
source = int(args.source)
cap = cv2.VideoCapture(source)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
else:
source = str(args.source)
cap = cv2.VideoCapture(source)
# 循环读取视频流或摄像头的每一帧,并进行目标检测
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 调整图像大小
img = cv2.resize(frame, (640, 480))
# 将图像转换为PyTorch Tensor
img = torch.from_numpy(img.transpose(2, 0, 1)).float().div(255.0).unsqueeze(0)
# 在CPU或GPU上运行模型
if device.type != 'cpu':
img = img.to(device)
# 运行模型进行目标检测
pred = model(img)[0]
# 非极大值抑制
pred = non_max_suppression(pred, 0.4, 0.5)
# 循环处理每个检测到的物体
for i, det in enumerate(pred):
if len(det):
# 缩放坐标,适应原始图像大小
det[:, :4] = scale_coords(img.shape[2:], det[:, :4], frame.shape).round()
# 循环打印每个检测到的物体
for *xyxy, conf, cls in reversed(det):
label = f'{names[int(cls)]} {conf:.2f}'
plot_one_box(xyxy, frame, label=label, color=colors(int(cls)), line_thickness=3)
# 显示图像和识别结果
cv2.imshow('frame', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# 释放摄像头或视频流,关闭窗口
cap.release()
cv2.destroyAllWindows()
```
注意,这个程序使用了一些辅助函数和工具类,需要先安装YOLOv5项目的依赖:
```
pip install -U -r yolov5/requirements.txt
```
另外,这个程序用到了一个 `plot_one_box` 函数,用于在图像上画出边界框和标签,它的实现如下:
```python
def plot_one_box(xyxy, im, color=None, label=None, line_thickness=None):
tl = line_thickness or round(0.002 * max(im.shape[0:2])) + 1 # line thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(xyxy[0]), int(xyxy[1])), (int(xyxy[2]), int(xyxy[3]))
cv2.rectangle(im, 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(im, c1, c2, color, -1, cv2.LINE_AA) # filled
cv2.putText(im, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
```
这个函数需要在程序中定义,或者从YOLOv5项目的 `utils/general.py` 文件中复制。
阅读全文