Python学习day8
今天运用所学的知识来尝试解决一下工作中的问题(我的工作是做视频相关的)
首先,我想要通过代码检查一个视频文件的质量,例如有没有丢帧,如果有丢帧的情况,会造成播放视频会卡顿
搜了一些资料,要判断一个视频文件是否丢帧,可借助Python的OpenCV库来实现
第一步是安装OpenCV库,在这一步遇到了挺多困难浪费了很多时间,在此不再对遇到的问题做具体列举,只写一下能成功的方法
第一步:确保正确安装了环境变量
在cmd命令行发送指令python --version,若能正确返回python的版本,则证明环境变量是配置正常的

若未返回python版本,则需要配置一下环境变量
可以在电脑上直接搜环境变量

点击环境变量

在系统变量这里找到Path

添加 Python 安装目录(例如C:\Python39)和 Python 安装目录下的Scripts文件夹路径(例如C:\Python39\Scripts)

保存配置后,在cmd命令行发送指令python --version,若能正确返回python的版本,则证明环境变量配置成功
第二步:在命令行中安装opencv-python库
在cmd中发送指令pip install opencv-python即可成功安装
到此,前期准备结束,接下来是代码部分
1. 打开视频文件:使用cv2.VideoCapture打开视频文件。
2. 逐帧读取视频:使用cap.read()逐帧读取视频,并通过cap.get(cv2.CAP_PROP_POS_FRAMES)获取当前帧的序号。
3. 检查帧序号的连续性:比较当前帧的序号和前一帧的序号,如果不连续,则认为存在丢帧现象。
import cv2
def check_frame_loss(video_path):
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print("无法打开视频文件")
return
# 获取视频的帧率和总帧数
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 计算理论时长(秒)
theoretical_duration = frame_count / fps
# 实际读取视频帧并计时
actual_frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
actual_frame_count += 1
# 释放资源
cap.release()
# 计算实际时长(秒)
actual_duration = actual_frame_count / fps
# 判断是否丢帧
if abs(actual_duration - theoretical_duration) > 0.1:
print("视频可能存在丢帧现象")
else:
print("视频未发现丢帧现象")
if __name__ == "__main__":
video_file = 'C:\\Users\\zt\\Desktop\\CH1_20250312_133207_000000.ts'
check_frame_loss(video_file)
找了一个有丢帧的录像文件,运行后的结果如下

能正确检测中视频中的丢帧情况
改一下需求:
1. 检测某个文件夹内所有视频文件是否有丢帧
2. 打印每个文件夹是否有丢帧,总共丢了多少帧
代码如下:
import cv2
import os
def check_frame_loss(video_path):
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
print(f"无法打开视频文件: {video_path}")
return 0
# 获取视频的帧率和总帧数
fps = cap.get(cv2.CAP_PROP_FPS)
frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
# 计算理论时长(秒)
theoretical_duration = frame_count / fps
# 实际读取视频帧并计时
actual_frame_count = 0
while True:
ret, frame = cap.read()
if not ret:
break
actual_frame_count += 1
# 释放资源
cap.release()
# 计算实际时长(秒)
actual_duration = actual_frame_count / fps
# 计算丢帧数量
lost_frames = int(abs(frame_count - actual_frame_count))
return lost_frames
def check_all_videos_in_folder(folder_path):
total_lost_frames = 0
for root, dirs, files in os.walk(folder_path):
for file in files:
if file.lower().endswith(('.mp4', '.avi', '.mov', '.ts')):
video_path = os.path.join(root, file)
lost_frames = check_frame_loss(video_path)
total_lost_frames += lost_frames
if lost_frames > 0:
print(f"视频 {video_path} 存在丢帧,丢帧数量: {lost_frames}")
else:
print(f"视频 {video_path} 未发现丢帧")
print(f"文件夹内所有视频总共丢帧数量: {total_lost_frames}")
if __name__ == "__main__":
folder = 'C:\\Users\\zt\\Desktop\\record'
check_all_videos_in_folder(folder)
运行后:

补充一下了解到的获取当前帧序号的原理:
视频文件的底层结构
视频文件通常由一系列的帧(图像)组成,这些帧按照一定的时间顺序排列,形成连续的动态画面。视频文件格式(如 MP4、AVI、TS 等)会定义如何存储这些帧以及相关的元数据。元数据包含了视频的基本信息,例如帧率、分辨率、时长等,还可能记录了每帧在文件中的位置信息。
OpenCV 对视频流的管理
OpenCV 使用cv2.VideoCapture类来读取视频文件。当你创建一个cv2.VideoCapture对象并打开视频文件时,OpenCV 会解析视频文件的元数据,建立一个视频流的读取指针。这个指针指向视频文件中的当前位置,随着视频帧的读取,指针会逐帧向后移动。
获取当前帧序号的方法
在 OpenCV 中,你可以使用cap.get(cv2.CAP_PROP_POS_FRAMES)方法来获取当前帧的序号,其原理如下:
初始化:当你调用cv2.VideoCapture打开视频文件时,读取指针初始指向视频的第一帧,此时cap.get(cv2.CAP_PROP_POS_FRAMES)返回值为 0。
逐帧读取:每次调用cap.read()方法读取一帧时,OpenCV 会将读取指针向后移动到下一帧的位置,并更新cv2.CAP_PROP_POS_FRAMES的值。因此,在读取每帧后调用cap.get(cv2.CAP_PROP_POS_FRAMES),就可以得到当前帧在视频中的序号。
序号连续性:正常情况下,视频帧的序号是连续递增的。例如,第一帧序号为 0,第二帧序号为 1,以此类推。如果在读取过程中发现序号不连续,可能意味着视频存在丢帧现象。
今天主要了解了一下如何实现检查一个视频是否有丢帧情况,后续的学习主要围绕工作相关的,如何通过代码提高效率的方法,欢迎大家监督~
更多推荐



所有评论(0)