这段代码实现了对给定视频进行检测和分割的功能,具体步骤如下:

  1. 导入库

    • cv2: 用于读取和处理图像和视频。
    • pandas: 用于数据处理和分析。
    • numpy: 用于数值计算。
    • PIL: 用于图像处理。
    • torch: 用于深度学习模型和张量操作。
    • torchvision.transforms: 用于图像预处理。
    • tqdm: 用于显示处理进度条。
  2. 定义 Sobel 类

    • 该类继承自 nn.Module 类,用于实现 Sobel 算子,计算图像的梯度幅值。
    • __init__ 函数中定义了一个卷积层 filter,输入通道数为 1,输出通道数为 2,卷积核大小为 3x3,步长为 1,填充为 1,没有偏置项。
    • 创建了两个 Sobel 算子 GxGy,并将它们拼接在一起形成一个 2x3x3 的张量 G
    • G 设置为 filter 的权重,不可训练。
    • forward 函数对输入图像进行滤波操作,计算梯度幅值,并返回结果。
  3. 定义 AverageFilter 类

    • 该类继承自 nn.Module 类,用于实现平均滤波。
    • __init__ 函数中定义了一个卷积层 filter,输入通道数为 1,输出通道数为 1,卷积核大小为 ksize,步长为 max((ksize-1)//2, 0),填充为 1,没有偏置项。
    • 创建了一个大小为 ksize x ksize 的全 1 矩阵 G,并将其设置为 filter 的权重,不可训练。
    • forward 函数对输入图像进行平均滤波操作,并返回结果。
  4. 定义 DataBuffer 类

    • 该类用于创建一个队列,用于存储处理中的帧。
    • __init__ 函数接受一个参数 num,表示队列的最大长度。
    • put 方法用于向队列中添加元素,如果队列长度超过最大长度,则删除最早的元素并返回。
    • get 方法用于获取队列中的元素,去除其中的空值并返回。
    • is_full 方法用于判断队列是否已满,如果队列长度小于最大长度,则返回 False,否则返回 True
  5. 定义 get_video_file_list 函数

    • 该函数用于获取指定文件夹下的所有视频文件路径。
    • 函数接受一个文件夹路径作为参数。
    • 获取文件夹下的所有文件名。
    • 遍历文件名,将以 ".mp4"、".flv"、".mts"、".avi"、".ts" 结尾的文件路径添加到 video_paths 列表中。
    • 返回 video_paths 列表。
  6. 设置设备和模型路径

    • 判断是否有可用的 GPU,如果有则使用 cuda,否则使用 cpu。
    • 设置训练好的模型的路径。
  7. 定义图像预处理的 transform

    • 将图像转换为张量。
    • 调整图像大小为 256x256。
    • 标准化图像像素值,将像素值从 [0, 255] 缩放到 [-1, 1]。
  8. 创建 AverageFilter 实例 blur,并将其移动到设备上

  9. 设置步长 step 和灰度阈值 mask_gray_th

  10. 定义视频文件夹路径 PATHS

  11. 遍历视频文件夹路径 PATHS:

  • 获取视频文件夹下的所有视频文件路径 video_paths
  1. 遍历视频文件路径 video_paths:
  • 输出当前处理的视频路径。
  • 如果视频路径以 "_process.mp4" 结尾,则跳过该视频。
  • 打开视频文件,获取帧率、帧宽和帧高等信息。
  • 设置下采样比例 down_sample_ratio 为 2。
  • 获取视频的帧数 maxf,并将其与 1 取最大值。
  • 设置最小帧数 min_frame 为 0,最大帧数 max_framemaxf+1
  • 创建保存路径 save_path 为视频文件所在文件夹路径 + "/processed_videos"。
  • 如果保存路径不存在,则创建该文件夹。
  • 根据视频文件名和文件类型构建保存路径 save_pathsave_path_croppedsave_path_contour
  • 创建 DataBuffer 实例 obufffbuff,最大长度为 16。
  • 设置裁剪下限 crop_lowerh * 17/36
  • 创建空的轮廓列表 contours
  • 设置进度步长 progress_step 为 0。
  • 创建矩形 rect,初始值为 [1080, 1080, -1, -1]。
  • 创建视频写入对象 videoWriter_croppedvideoWriter_contour,设置输出路径、帧率和帧大小。
  • 设置视频的读取位置为最小帧数 min_frame
  • 进行检测和分割的循环,从最小帧数 min_frame 到最大帧数 max_frame+1
    • 读取视频帧,如果帧索引 frame_idx 不是下采样的帧,则跳过。
    • 如果读取成功:
      • 将帧添加到 obuff 队列中。
      • 将帧转换为灰度图像,并裁剪掉下部分,然后转换为 PIL 图像。
      • 进行图像预处理和类型转换,并将结果放入 fbuff 队列中。
      • 如果 fbuff 队列未满,则跳过本次循环。
      • 如果帧索引 frame_idxstep 的倍数:
        • fbuff 队列中的图像拼接为一个张量 inputs,形状为 (1, n, h, h),其中 n 为 fbuff 队列的长度。
        • 运行模型,获取预测的掩膜 pred_mask
        • 对预测的掩膜进行插值和平滑处理,得到最终的二值掩膜 pred_mask
        • 将二值掩膜转换为灰度图像,并计算轮廓 contours
        • 如果存在轮廓:
          • 对轮廓按面积排序,取面积最大的轮廓。
          • 将轮廓的坐标加上裁剪下限 crop_lower,并更新最大轮廓 max_counter
    • 如果存在轮廓:
      • 更新矩形 rect 的边界坐标。
    • obuff 队列中第 8 个帧复制给 output_frame_cropped
    • 创建与 output_frame_cropped 相同大小的全零图像 output_frame_contour
    • output_frame_contour 上绘制最大轮廓。
  1. 对目标区域进行裁剪
  • 计算目标区域的宽度和高度,并根据其比例进行调整,确保目标区域被完整地包含在裁剪后的图像中。
  • 重新创建视频写入对象,设置新的帧大小为裁剪后的图像大小。
  • 读取裁剪后的视频,将目标区域裁剪出来,并写入新的视频文件。
  1. 清理
  • 释放所有资源,并删除临时文件。

原文地址: http://www.cveoy.top/t/topic/fCdj 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录