当前位置:   article > 正文

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

yolov视频检测保存截图

前言

在笔者的第一篇 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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

解析

这段代码主要分为两个部分:一个是将图像序列合成视频的函数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目标检测模型来实现实时视频处理。无论是在科研项目中,还是在实际应用中,这种技术都能大大提高我们的工作效率和项目质量。希望本文的内容能够为读者提供有益的参考,帮助大家更好地理解并应用这些技术。

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/1015320
推荐阅读
相关标签
  

闽ICP备14008679号