同步上一期视频关键帧提取方法:

视频提取关键帧的三种方式【已调通】_君临天下tjm的博客-CSDN博客_视频关键帧提取关键代码如下:# -*- coding: utf-8 -*-"""this key frame extract algorithm is based on interframe difference.The principle is very simpleFirst, we load the video and compute the interframe difference between each framesThen, we can choose one of t...https://blog.csdn.net/shanxiderenheni/article/details/124499862

项目中可以直接导入该工具类KeyFramesExtractUtils.py,三种取帧方式通过参数选择,method可以取"use_top_order"、"use_thresh"、"use_local_maxima"中的任何一种,第三种方式效果最佳,默认也是"use_local_maxima"。

优化点:

key_frame = 10  # 所隔帧数
cap.set(cv2.CAP_PROP_POS_FRAMES, j)  # 这里的cv2.CAP_PROP_POS_FRAMES参数是说:取第j帧之后的那一帧
j += key_frame
......
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
视频提取关键帧工具类KeyFramesExtractUtils.py完整代码如下:
# -*- coding: utf-8 -*-
"""
this key frame extract algorithm is based on interframe difference.The principle is very simple
First, we load the video and compute the interframe difference between each framesThen, we can choose one of these three methods to extract keyframes, which are
all based on the difference method:1. use the difference orderThe first few frames with the largest average interframe differenceare considered to be key frames.
2. use the difference thresholdThe frames which the average interframe difference are large than thethreshold are considered to be key frames.
3. use local maximumThe frames which the average interframe difference are local maximum areconsidered to be key frames.It should be noted that smoothing the average difference value beforecalculating the local maximum can effectively remove noise to avoidrepeated extraction of frames of similar scenes.After a few experiment, the third method has a better key frame extraction effect.
"""
import cv2
import operator
import numpy as np
import matplotlib.pyplot as plt
import sys
import time
from scipy.signal import argrelextrema# USE_LOCAL_MAXIMA=True,效果还行,时间有点长,54张图,包括一张差异趋势图
# 使用cv2.CAP_PROP_POS_FRAMES间隔取帧,主要消耗CPU,效率比内存高,效果更好# 视频提取关键帧工具类
class KeyFramesExtractUtils:# 初始化def __init__(self, video_path=None, save_path=None):self.video_path = video_pathself.save_path = save_path# 提取关键帧def extract_keyframe(self, method="use_local_maxima"):print(sys.executable)print("method===>", method)# fixed threshold valuethresh = 0.6# Number of top sorted framesnum_top_frames = 50# smoothing window sizelen_window = int(50)print("target video: " + self.video_path)print("frame save directory: " + self.save_path)# load video and compute diff between framescap = cv2.VideoCapture(str(self.video_path))curr_frame = Noneprev_frame = Noneframe_diffs = []frames = []video_frames = []key_frame = 10  # 所隔帧数t0_start = time.time()k = 0j = 0while True:if key_frame >= 1:t1_start = time.time()print("j======>", j)cap.set(cv2.CAP_PROP_POS_FRAMES, j)  # 这里的cv2.CAP_PROP_POS_FRAMES参数是说:取第j帧之后的那一帧j += key_framesuccess, frame = cap.read()if not success:print("第一次视频帧读取完毕!")breakgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)curr_frame = grayif curr_frame is not None and prev_frame is not None:# logic herediff = cv2.absdiff(curr_frame, prev_frame)diff_sum = np.sum(diff)diff_sum_mean = diff_sum / (diff.shape[0] * diff.shape[1])frame_diffs.append(diff_sum_mean)temp_frame = Frame(k, diff_sum_mean)frames.append(temp_frame)video_frames.append(frame)k = k + 1prev_frame = curr_framet1_end = time.time()print("计算一次差分耗时:", (t1_end - t1_start), "s")cap.release()t0_end = time.time()print("计算共耗时:", (t0_end - t0_start), "s")t_start = time.time()# compute keyframekeyframe_id_set = set()if method == "use_top_order":print("---------------Using use_top_order---------------")# sort the list in descending orderframes.sort(key=operator.attrgetter("diff"), reverse=True)for keyframe in frames[:num_top_frames]:keyframe_id_set.add(keyframe.id)elif method == "use_thresh":print("---------------Using Threshold---------------")for i in range(1, len(frames)):if rel_change(np.float(frames[i - 1].diff), np.float(frames[i].diff)) >= thresh:keyframe_id_set.add(frames[i].id)else:print("---------------Using Local Maxima---------------")diff_array = np.array(frame_diffs)sm_diff_array = smooth(diff_array, len_window)frame_indexes = np.asarray(argrelextrema(sm_diff_array, np.greater))[0]for i in frame_indexes:keyframe_id_set.add(frames[i - 1].id)plt.figure(figsize=(40, 20))plt.locator_params(numticks=100)plt.stem(sm_diff_array)plt.savefig(self.save_path + 'plot.png')for idx in keyframe_id_set:name = "keyframe_" + str(idx) + ".jpg"cv2.imwrite(self.save_path + name, video_frames[idx])t_end = time.time()print("取帧共耗时:", (t_end - t_start), "s")class Frame:"""class to hold information about each frame"""def __init__(self, id, diff):self.id = idself.diff = diffdef __lt__(self, other):if self.id == other.id:return self.id < other.idreturn self.id < other.iddef __gt__(self, other):return other.__lt__(self)def __eq__(self, other):return self.id == other.id and self.id == other.iddef __ne__(self, other):return not self.__eq__(other)def rel_change(a, b):x = (b - a) / max(a, b)print(x)return xdef smooth(x, window_len=13, window='hanning'):"""smooth the data using a window with requested size."""print(len(x), window_len)s = np.r_[2 * x[0] - x[window_len:1:-1],x, 2 * x[-1] - x[-1:-window_len:-1]]# print(len(s))if window == 'flat':  # moving averagew = np.ones(window_len, 'd')else:w = getattr(np, window)(window_len)y = np.convolve(w / w.sum(), s, mode='same')return y[window_len - 1:-window_len + 1]if __name__ == "__main__":keyFrame = KeyFramesExtractUtils(video_path="e956ed44fffe4bfb97cf23474fb48ef3.avi", save_path="./extract_result/")keyFrame.extract_keyframe(method="use_local_maxima")# 计算共耗时: 307.6547501087189 s
# 取帧共耗时: 22.484756231307983 s

提取的关键帧如下:

检测结果总结:视频帧的提取率约为1.66‰,21m15s的视频,耗时约330s(即5分30秒)。

视频提取关键帧工具类KeyFramesExtractUtils.py,动态支持三种取帧方式,关键参数可配置,代码经过优化处理,效果和性能更好。相关推荐

  1. 视频提取关键帧的三种方式【已调通】

    推荐优化后的视频关键帧提取方法,已经包装成工具类,代码做了优化,性能和效果更好. 视频提取关键帧工具类KeyFramesExtractUtils.py,动态支持三种取帧方式,关键参数可配置,代码经过优 ...

  2. Spring视频转码工具类ffmpeg

    使用的是ffmepg,需要先下载,然后解压到指定文件夹, 其中的变量ffmpegPath指定的是ffmepg解压后的exe路径 这里看到processVideoFormat()方法中,推荐一律使用Mg ...

  3. 3个简单好用的视频提取字幕工具,效率极高,建议收藏

    分享3个简单且效率非常高的视频提取字幕工具,提取后的字幕不仅可以保存为文档,还能直接导出为字幕格式的文件,不管是识别中文还是英文都能一键将视频字幕提取成功. 1.网易见外工作台 一个免费的在线各种音视 ...

  4. python视频提取关键帧_如何使用Python提取视频的关键帧?

    在很多场景下,我们不想或者不能处理视频的每一帧图片,这时我们希望能够从视频中提取出一些重要的帧进行处理,这个过程我们称为视频关键帧提取. 关键帧提取算法多种多样,如何实现主要取决于你对于关键帧的定义. ...

  5. Python正则表达式工具类文件的封装实例,提供了多个实例,并且在代码中包含中文注释

    Python正则表达式工具类文件的封装实例,提供了多个实例,并且在代码中包含中文注释 import reclass RegexUtils:'''正则表达式工具类'''def __init__(self ...

  6. Javascript定义类(class)的三种方法

    将近20年前,Javascript诞生的时候,只是一种简单的网页脚本语言.如果你忘了填写用户名,它就跳出一个警告. 如今,它变得几乎无所不能,从前端到后端,有着各种匪夷所思的用途.程序员用它完成越来越 ...

  7. 视频监控系统中的流媒体服务器,视频监控系统中的流媒体服务器、直写和全切换三种取流架构方案...

    原标题:视频监控系统中的流媒体服务器.直写和全切换三种取流架构方案 一.流媒体服务器架构 前摄像头视频信号通过转发流媒体服务器转发至上壁面显示和终端接入,视频存储磁阵列通过流媒体存储服务器写入.实时流 ...

  8. python视频提取关键帧_一种视频关键帧提取算法的制作方法

    本发明属于信息安全技术领域,涉及视频内容信息的提取,具体来说,是一种视频关键帧提取算法. 背景技术: 随着Internet的应用和普及,多媒体信息检索系统对社会各领域产生越来越大的影响.传统的信息检索 ...

  9. 抖音视频解析的工具类

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 一.一个解析抖音分析链接的工具类 import java.io.IOException; import java.util.HashM ...

最新文章

  1. 预见未来丨机器学习:未来十年研究热点
  2. 人民日报:中国 31 个省市区最好的大学
  3. LeetCode--27. 移除元素(双指针)
  4. 网信办拟规定:平台未经用户同意不得强制订阅关注账号;Twitter回应大范围宕机;Krita 4.4.0发布|极客头条
  5. windows 10卸载(注销)WSL,注销(卸载)当前安装的Linux的Windows子系统
  6. 如何批量修改Word文档Mathtype公式字体
  7. 2022年最新微博批量删除代码_自动化删除新浪微博代码
  8. Redis缓存雪崩,如何解决?
  9. SQLiteDatabaseLockedException: database is locked
  10. nowcoder16638 carpet
  11. mysql怎么创建外表_MYSQL数据去重与外表填充
  12. 程序化广告(2):程序化广告的参与者
  13. 自定义下拉回弹View-掌握View冲突处理
  14. PPT突然不能翻页了
  15. 利用CSS3动画属性实现轮播图切换图片时出现附近内容抖动的解决办法。
  16. random.seed()的用法
  17. 游戏y欧系家角色设计没灵感怎么办?
  18. 英语面试对话场景[进入外企的敲门砖]
  19. 相位式激光测距全套方案
  20. 传统蒙文字体_蒙古文

热门文章

  1. growup怎么读_grow up是什么意思_grow up怎么读_grow up翻译_用法_发音_词组_同反义词_向上生长-新东方在线英语词典...
  2. JAVA——多线程【线程终止、中断、插队】
  3. 电平是什么?单片机的I/0口输入和输出,1和0是什么?什么是TTL电平?TTL电平分析?TTL、CMOS、RS232、RS485电平差异?usb转ttl?CH340模块驱动安装?电平之间的转换?
  4. 高德地图开发:Marker 与 Polyline
  5. 重磅!南京大学发布2023年博士研究生招生简章!
  6. python动态爬取知乎_Python新手爬虫:爬取搜狗图片(动态)
  7. JSP中自定义jstl标签
  8. 基于MVC个人信息管理系统
  9. mysql in 排序 无数据混乱_mysql in查询 结果乱序 引发的思考
  10. Spark创建空的DataFrame