YOLO系列笔记(十六)—— 图片合成视频并通过yolov8目标识别代码

前言

在笔者的第一篇 YOLO 笔记文章中,提到 YOLO 网络相对于二阶段网络的一个显著优势是可以进行实时的目标识别,因此非常适合用于监控等需要对视频进行实时目标识别的场景。在这篇笔记中,笔者将介绍如何将图片合成为视频,以及如何调用 YOLOv8 对视频中的物体进行目标识别的代码。通过这篇文章,读者可以学习到图像处理和目标识别的具体实现方法,并将其应用到实际项目中。

代码

import os
import cv2

def img_video_merge(img_dir, video_path, frame_rate, repeat=5, frame_skip=1):
    # 获取所有图像文件,过滤掉非图像文件
    file_list = sorted([f for f in os.listdir(img_dir) if f.lower().endswith(('.png', '.jpg', '.jpeg'))])

    # 检查目录中是否有图像文件
    if not file_list:
        print("No image files found in the directory.")
        return

    # 跳帧处理:每隔frame_skip张图片读取一次
    file_list = file_list[::frame_skip]

    # 读取第一张图像以获取帧大小
    cv_src = cv2.imread(os.path.join(img_dir, file_list[0]))

    # 检查图像是否读取成功
    if cv_src is None:
        print(f"Failed to read the first image: {file_list[0]}")
        return

    # 创建输出视频的目录
    os.makedirs(os.path.dirname(video_path), exist_ok=True)

    # 使用H.264编解码器
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')

    # 获取图像的高度和宽度
    height, width, channels = cv_src.shape

    # 帧速率和帧大小
    frame_size = (width, height)

    # 创建VideoWriter对象
    out = cv2.VideoWriter(video_path, fourcc, frame_rate, frame_size)

    # 检查VideoWriter对象是否打开成功
    if not out.isOpened():
        print(f"Failed to open VideoWriter with path: {video_path}")
        return

    for file in file_list:
        img_path = os.path.join(img_dir, file)
        cv_dst = cv2.imread(img_path)

        if cv_dst is None:
            print(f"Failed to read image: {file}")
            continue

        # 将同一帧写入多次以增加显示时间
        for _ in range(repeat):
            out.write(cv_dst)

    # 释放VideoWriter对象
    out.release()
    print(f"Video saved to {video_path}")


def process_video(video_path, yolov8):
    # 打开视频文件,创建视频捕获对象cap。
    cap = cv2.VideoCapture(video_path)
    # 检查视频文件是否成功打开。
    if not cap.isOpened():
        print(f"Error: Could not open video {video_path}")
        return
    # 循环读取视频帧,只要视频文件还未读完并且打开状态良好。
    while cap.isOpened():
        # 读取下一帧,ret 表示读取成功与否,frame 是读取的帧图像。
        ret, frame = cap.read()
        # 是否到达视频末尾
        if not ret:
            break

        # 再进行目标识别
        yolov8(frame)

        # 绘制识别结果
        result_frame = yolov8.draw_detections(frame)

        # 显示处理后的帧图像。
        cv2.imshow('Processed Frame', result_frame)
        # 等待 1 毫秒并检查是否有按键按下,如果按下的是 q 键,则跳出循环。
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # 释放视频捕获对象,关闭视频文件。
    cap.release()
    # 关闭所有 OpenCV 窗口。
    cv2.destroyAllWindows()


# 主函数
if __name__ == '__main__':
    # 初始化模型
    yolov8 = YOLODet('object.onnx', conf_thres=0.3, iou_thres=0.5)
    imgs_dir = r'./images'
    video_path = r'./video.mp4'
    
    frame_rate = 25  # 设置较高的帧速率,例如25帧每秒
    repeat = 5  # 每帧重复写入5次
    frame_skip = 5  # 设置跳帧,每隔5帧取一帧
    
    #生成视频
    img_video_merge(imgs_dir, video_path, frame_rate, repeat, frame_skip)

    # 处理视频
    process_video(video_path, yolov8)

解析

这段代码主要分为两个部分:一个是将图像序列合成视频的函数img_video_merge,另一个是处理视频进行目标识别的函数process_video。以下是详细的分析:

1. img_video_merge 函数

功能:将指定目录中的图像文件合成为一个视频文件。

参数:

  • img_dir:存放图像的目录路径。
  • video_path:输出视频文件的路径。
  • frame_rate:视频的帧速率(每秒显示的帧数)。
  • repeat:每帧在视频中重复写入的次数,默认值为5。
  • frame_skip:每隔frame_skip张图片读取一次,默认值为1。

实现步骤:

  • 获取目录中所有图像文件,并过滤掉非图像文件(根据文件扩展名)。
  • 检查目录中是否存在图像文件,如果没有,输出提示并返回。
  • 跳帧处理,按照指定的frame_skip值进行筛选。
  • 读取第一张图像以获取帧的大小(高度和宽度)。
  • 创建输出视频的目录(如果不存在)。
  • 使用H.264编解码器(mp4v)创建VideoWriter对象。
  • 检查VideoWriter对象是否成功打开,如果失败,输出提示并返回。
  • 依次读取每张图像,并将其写入视频,每帧重复写入repeat次。 释放VideoWriter对象,保存视频文件并输出提示。

2. process_video 函数

功能:处理视频进行目标识别,并显示处理后的帧。

参数:

  • video_path:要处理的视频文件路径。
  • yolov8:YOLOv8目标检测模型对象。

实现步骤:

  • 打开视频文件,创建视频捕获对象cap。
  • 检查视频文件是否成功打开,如果失败,输出提示并返回。
  • 循环读取视频帧,直到视频结束或出现错误。
  • 读取下一帧,并检查是否到达视频末尾。
  • 使用YOLOv8模型进行目标识别,并绘制识别结果。
  • 显示处理后的帧图像。 检查是否有按键按下,如果按下的是q键,则跳出循环。
  • 释放视频捕获对象,关闭所有OpenCV窗口。

3. 主函数

**功能:**初始化模型并调用图像合成视频和视频处理函数。

步骤:

  • 初始化YOLOv8目标检测模型。
  • 设置图像目录路径和视频输出路径。
  • 设置帧速率、重复次数和跳帧参数。
  • 调用img_video_merge函数生成视频。
  • 调用process_video函数处理生成的视频。

结语

在本文中,我们详细探讨了如何利用Python和OpenCV将图像序列合成视频,并在视频中进行目标识别。这个过程不仅涉及了图像处理与视频编解码技术,还展示了如何集成YOLOv8目标检测模型来实现实时视频处理。无论是在科研项目中,还是在实际应用中,这种技术都能大大提高我们的工作效率和项目质量。希望本文的内容能够为读者提供有益的参考,帮助大家更好地理解并应用这些技术。

如果您有任何疑问或建议,欢迎在评论区留言。感谢您的阅读与支持!

  • 13
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值