Python 视频处理代码详解:检测与分割
这段代码实现了对给定视频进行检测和分割的功能,具体步骤如下:
-
导入库
cv2: 用于读取和处理图像和视频。pandas: 用于数据处理和分析。numpy: 用于数值计算。PIL: 用于图像处理。torch: 用于深度学习模型和张量操作。torchvision.transforms: 用于图像预处理。tqdm: 用于显示处理进度条。
-
定义 Sobel 类
- 该类继承自
nn.Module类,用于实现 Sobel 算子,计算图像的梯度幅值。 - 在
__init__函数中定义了一个卷积层filter,输入通道数为 1,输出通道数为 2,卷积核大小为 3x3,步长为 1,填充为 1,没有偏置项。 - 创建了两个 Sobel 算子
Gx和Gy,并将它们拼接在一起形成一个 2x3x3 的张量G。 - 将
G设置为filter的权重,不可训练。 forward函数对输入图像进行滤波操作,计算梯度幅值,并返回结果。
- 该类继承自
-
定义 AverageFilter 类
- 该类继承自
nn.Module类,用于实现平均滤波。 - 在
__init__函数中定义了一个卷积层filter,输入通道数为 1,输出通道数为 1,卷积核大小为ksize,步长为max((ksize-1)//2, 0),填充为 1,没有偏置项。 - 创建了一个大小为
ksize x ksize的全 1 矩阵G,并将其设置为filter的权重,不可训练。 forward函数对输入图像进行平均滤波操作,并返回结果。
- 该类继承自
-
定义 DataBuffer 类
- 该类用于创建一个队列,用于存储处理中的帧。
__init__函数接受一个参数num,表示队列的最大长度。put方法用于向队列中添加元素,如果队列长度超过最大长度,则删除最早的元素并返回。get方法用于获取队列中的元素,去除其中的空值并返回。is_full方法用于判断队列是否已满,如果队列长度小于最大长度,则返回False,否则返回True。
-
定义 get_video_file_list 函数
- 该函数用于获取指定文件夹下的所有视频文件路径。
- 函数接受一个文件夹路径作为参数。
- 获取文件夹下的所有文件名。
- 遍历文件名,将以 ".mp4"、".flv"、".mts"、".avi"、".ts" 结尾的文件路径添加到
video_paths列表中。 - 返回
video_paths列表。
-
设置设备和模型路径
- 判断是否有可用的 GPU,如果有则使用 cuda,否则使用 cpu。
- 设置训练好的模型的路径。
-
定义图像预处理的 transform
- 将图像转换为张量。
- 调整图像大小为 256x256。
- 标准化图像像素值,将像素值从 [0, 255] 缩放到 [-1, 1]。
-
创建 AverageFilter 实例 blur,并将其移动到设备上
-
设置步长 step 和灰度阈值 mask_gray_th
-
定义视频文件夹路径 PATHS
-
遍历视频文件夹路径 PATHS:
- 获取视频文件夹下的所有视频文件路径
video_paths。
- 遍历视频文件路径 video_paths:
- 输出当前处理的视频路径。
- 如果视频路径以 "_process.mp4" 结尾,则跳过该视频。
- 打开视频文件,获取帧率、帧宽和帧高等信息。
- 设置下采样比例
down_sample_ratio为 2。 - 获取视频的帧数
maxf,并将其与 1 取最大值。 - 设置最小帧数
min_frame为 0,最大帧数max_frame为maxf+1。 - 创建保存路径
save_path为视频文件所在文件夹路径 + "/processed_videos"。 - 如果保存路径不存在,则创建该文件夹。
- 根据视频文件名和文件类型构建保存路径
save_path和save_path_cropped和save_path_contour。 - 创建
DataBuffer实例obuff和fbuff,最大长度为 16。 - 设置裁剪下限
crop_lower为h * 17/36。 - 创建空的轮廓列表
contours。 - 设置进度步长
progress_step为 0。 - 创建矩形
rect,初始值为 [1080, 1080, -1, -1]。 - 创建视频写入对象
videoWriter_cropped和videoWriter_contour,设置输出路径、帧率和帧大小。 - 设置视频的读取位置为最小帧数
min_frame。 - 进行检测和分割的循环,从最小帧数
min_frame到最大帧数max_frame+1:- 读取视频帧,如果帧索引
frame_idx不是下采样的帧,则跳过。 - 如果读取成功:
- 将帧添加到
obuff队列中。 - 将帧转换为灰度图像,并裁剪掉下部分,然后转换为 PIL 图像。
- 进行图像预处理和类型转换,并将结果放入
fbuff队列中。 - 如果
fbuff队列未满,则跳过本次循环。 - 如果帧索引
frame_idx是step的倍数:- 将
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上绘制最大轮廓。
- 读取视频帧,如果帧索引
- 对目标区域进行裁剪
- 计算目标区域的宽度和高度,并根据其比例进行调整,确保目标区域被完整地包含在裁剪后的图像中。
- 重新创建视频写入对象,设置新的帧大小为裁剪后的图像大小。
- 读取裁剪后的视频,将目标区域裁剪出来,并写入新的视频文件。
- 清理
- 释放所有资源,并删除临时文件。
原文地址: http://www.cveoy.top/t/topic/fCdj 著作权归作者所有。请勿转载和采集!