这段 Python 代码实现了一个实时的目标检测应用,具体来说是使用 YOLOv8 模型对外接摄像头(设备索引为 1)的视频流进行实时分析,检测其中的船只,并将检测结果以可视化的方式展示出来。代码通过循环不断读取摄像头的帧图像,进行目标检测,标注检测到的目标,并实时显示带有标注的图像,直到用户按下指定的按键('q' 键)退出程序。
代码详细说明
导入必要的库
python
import cv2
from ultralytics import YOLO
cv2
:OpenCV 库,用于处理计算机视觉任务,如读取摄像头视频流、图像显示等。YOLO
:来自ultralytics
库的类,用于加载和使用 YOLOv8 目标检测模型。
定义主函数 main
python
def main():
main
函数是整个程序的核心逻辑所在,后续的操作都在这个函数内进行。
加载 YOLOv8 模型
python
model = YOLO('yolov8n.pt')
使用YOLO
类加载预训练的 YOLOv8 模型,这里加载的是yolov8n.pt
模型,它是 YOLOv8 系列中的一个轻量级模型,适用于对性能要求较高的场景。
打开外接摄像头
python
cap = cv2.VideoCapture(1)
使用cv2.VideoCapture
函数尝试打开设备索引为 1 的外接摄像头,并将返回的摄像头对象赋值给cap
变量。
检查摄像头是否成功打开
python
if not cap.isOpened():print("无法打开外接摄像头,请检查设备连接或尝试其他设备索引。")return
通过cap.isOpened()
方法检查摄像头是否成功打开,如果未成功打开,打印错误提示信息并返回,终止程序执行。
主循环
python
while True:
这是一个无限循环,用于不断读取摄像头的帧图像并进行目标检测和显示。
读取摄像头的一帧图像
python
ret, frame = cap.read()
使用cap.read()
方法从摄像头读取一帧图像,返回值ret
表示是否成功读取(True
表示成功,False
表示失败),frame
是读取到的图像数据(一个 NumPy 数组)。
检查是否成功读取帧图像
python
if not ret:print("无法读取帧")break
如果ret
为False
,表示无法读取帧图像,打印错误信息并跳出循环,结束程序。
使用 YOLOv8 模型进行目标检测
python
results = model(frame)
将读取到的帧图像frame
输入到已加载的 YOLOv8 模型model
中,进行目标检测,检测结果存储在results
变量中。
获取检测结果并标注图像
python
annotated_frame = results[0].plot()
从检测结果results
中获取第一个(这里默认只有一个结果)检测结果,并使用plot
方法将检测到的目标标注在原始图像上,生成带有标注的图像annotated_frame
。
显示带有检测结果的图像
python
cv2.imshow('YOLOv8实时船只识别', annotated_frame)
使用cv2.imshow
函数在一个名为'YOLOv8实时船只识别'
的窗口中显示带有检测结果标注的图像annotated_frame
。
检查按键事件
python
if cv2.waitKey(1) & 0xFF == ord('q'):break
使用cv2.waitKey(1)
等待 1 毫秒的按键事件,返回按键的 ASCII 码值。如果按下的键是'q'
(其 ASCII 码值通过ord('q')
获取),则跳出循环,结束程序。
释放资源
python
cap.release()
cv2.destroyAllWindows()
cap.release()
:释放摄像头资源,关闭摄像头。cv2.destroyAllWindows()
:关闭所有由 OpenCV 创建的窗口。
程序入口
python
if __name__ == "__main__":main()
这是 Python 程序的入口点,当脚本直接运行时(而不是被其他模块导入),会调用main
函数,启动整个程序的执行。
注意事项
- 如果外接摄像头无法成功打开,可能需要尝试不同的设备索引(如 0、2 等),或者检查摄像头的连接和驱动是否正常。
- YOLOv8 模型的检测效果可能因场景和目标的不同而有所差异,对于特定的船只检测任务,可能需要对模型进行进一步的训练或微调以提高检测准确率。
完整代码
import cv2
from ultralytics import YOLOdef main():# 加载YOLOv8模型model = YOLO('yolov8n.pt')# 打开摄像头cap = cv2.VideoCapture(1)if not cap.isOpened():print("无法打开摄像头")returnwhile True:# 读取摄像头的一帧图像ret, frame = cap.read()if not ret:print("无法读取帧")break# 使用YOLOv8模型进行目标检测results = model(frame)# 获取检测结果annotated_frame = results[0].plot()# 显示带有检测结果的图像cv2.imshow('YOLOv8实时船只识别', annotated_frame)# 按 'q' 键退出循环if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放摄像头并关闭所有窗口cap.release()cv2.destroyAllWindows()if __name__ == "__main__":main()