为了提取关键帧,这里使用帧差法,语言为C语言,调用opencv库实现。

我们将视频第一帧设定为关键帧,后面的每一个帧与前一个关键帧进行像素帧差(灰度图),并设定阈值判断发生变化的像素点比例,通过此比例判断帧是否有发生突变,有发生突变的帧设定为关键帧并保存在特定文件夹中。以此循环将所有帧遍历完成即可。

在测试程序前,为了方便测试,我们将电影截取为两分钟的片段,不然太长了不方便测试,如果有备好的视频片段可以跳过这一步。在终端terminal打开窗口,输入以下命令,将(流浪地球)liulang_earth.mkv在一小时16分到一小时18分截取两分钟的视频片段并不保存为cutout1.mp4。之后对此两分钟视频提取关键帧。

 ffmpeg  -i ./liulang_earth.mkv -vcodec copy -acodec copy -ss 01:16:00 -to 01:18:00 ./cutout1.mp4 -y

程序我是放在文本编辑器中的,然后用g++编译。将pixels_cha.cpp编译生成pixels_cha可执行程序。g++编译命令如下

g++ `pkg-config opencv --cflags` pixels_cha.cpp -o pixels_cha `pkg-config opencv --libs

成功后再终端继续输入  ./pixels_cha   即可运行程序。如果使用其他编译器也是没有问题的。

程序如下

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>
#include <string.h>using namespace std;
using namespace cv;int main()
{system("color 2F");long currentFrame = 1;float p;VideoCapture cap;//这里放置需要提取关键字的视频cap.open("./cutout1.mp4");if(!cap.isOpened())//如果视频不能正常打开则返回{   cout<< "cannot open video!"<<endl;    return 0;}Mat frame_key;cap>>frame_key;if(frame_key.empty())cout<< "frame_key is empty!" << endl;imshow("fram_1",frame_key);waitKey(20);stringstream str;  str<<"./keyframes_pixels_cha/" <<currentFrame << ".jpg";  cout << str.str() << endl;  imwrite(str.str() , frame_key);  Mat frame;Mat previousImage,currentImage,resultImage; while(1){//printf(">>>>>>>>>>>>>00");currentFrame++;Mat frame;cap>>frame;//printf(">>>>>>>>>>>>>1");if(frame.empty()){cout<< "frame is empty!" << endl;break;}imshow("fram_1",frame);waitKey(20);Mat srcImage_base, hsvImage_base;Mat srcImage_test1, hsvImage_test1;srcImage_base = frame_key;srcImage_test1 = frame;                                  //将图像从BGR色彩空间转换到 HSV色彩空间cvtColor(srcImage_base, previousImage, CV_BGR2GRAY);cvtColor(srcImage_test1, currentImage, CV_BGR2GRAY);        //printf(">>>>>>>>>>>>>2");absdiff(currentImage,previousImage,resultImage);  //帧差法,相减//printf(">>>>>>>>>>>>>3");threshold(resultImage, resultImage, 10, 255.0, CV_THRESH_BINARY); //二值化,像素值相差大于20则置为255,其余为0printf(">>>>>>>>>>>>>1\n");float counter = 0;float num = 0;// 统计两帧相减后图像素for (int i=0; i<resultImage.rows; i++){ uchar *data = resultImage.ptr<uchar>(i); //获取每一行的指针for (int j=0;j<resultImage.cols; j++){num = num+1;if (data[j] == 255) //访问到像素值{counter = counter+1;}                  }}p = counter/num;// counter  num  p 分别为  有变化的像素点数  总像素点数目  比例printf(">>>>>>counter>>>>num>>>>p: %f  %f  %f  \n",counter,num,p);if (p > 0.55) //达到阈值的像素数达到一定的数量则保存该图像{//printf(">>>>>>>>>>>>>6");cout<< ">>>>>>>>>>>>>>>>>>>>.>>>>>>>.this frame is keyframe!"<<endl;frame_key = frame;cout << "正在写第" << currentFrame << "帧" << endl;  stringstream str;   //写视频保存目录,我的是  ./keyframes_pixels_cha/xx.jpg  xx为当前帧的序号str<<"./keyframes_pixels_cha/" <<currentFrame << ".jpg";  cout << str.str() << endl;  imwrite(str.str() , frame_key);  }else{cout<< ">>>>>>>>>>>>.this frame is not keyframe!"<<endl;}}
}

程序运行结果如下。第一帧不知道怎么不显示图,不过双击后仍然可以打开的。关键帧名字代表该帧属于视频中的第几帧。结果很理想,没有太多冗余帧。程序中可调参数为threshold(resultImage, resultImage, 10, 255.0, CV_THRESH_BINARY)中的 10,10为二值化阈值,还有p,p为比例。通过调节这两个参数可以优化关键帧提取结果。

如果有需要视频片段+程序的压缩包的,我已经在csdn上传的资源https://download.csdn.net/download/weixin_39704651/11181825

也可以在评论留下邮箱我发送过去。欢迎讨论~

c++调用opencv库实现视频关键帧提取--灰度帧差法相关推荐

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

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

  2. 两台电脑串口传输文件及调用opencv库编程显示图片和文本

    文章目录 一.两台电脑利用串口进行文件传输 (一).实验内容 (二).配置环境 (三).实验过程 (四).结果分析 二.在Ubuntu下基于Linux环境调用opencv库编程显示图片和文本 (一). ...

  3. python实现视频关键帧提取(基于帧间差分)

    python实现视频关键帧提取(基于帧间差分) 在很多场景下,我们不想或者不能处理视频的每一帧图片,这时我们希望能够从视频中提取出一些重要的帧进行处理,这个过程我们称为视频关键帧提取. 关键帧提取算法 ...

  4. 调用opencv库进行身份证号码识别主要流程

    如题,就是对身份证拍照,处理相应照片,识别出身份证号码 这里需要调用opencv库.opencv库包含了许多处理图像的函数,功能全面而且强大,兼容多种语言.如何配置可以自行搜索.  主要流程如下: 读 ...

  5. 在Ubuntu下用C/C++(或python)调用opencv库编程显示一张图片并在上面加文字

    一.实验内容 调用opencv库编程显示一张图片,并打开一个名为"logo.txt"的文本文件(其中只有一行文本文件,包括你自己的名字和学号),按照名字和学号去读取汉字24*24点 ...

  6. Python与OpenCV(一)——基于帧差法的运动目标检测程序分析

    OpenCV提供了强大的图像处理功能,与Python的结合堪称完美... 这一次,我们试一下用帧差法来完成对运动目标的检测与跟踪. 帧差法的原理是这样的:由于摄像机采集的视频序列具有连续性的特点,所以 ...

  7. opencv进阶-背景建模-(帧差法与混合高斯模型)

    背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤.如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算像素差从而获取到前景对象.但是在大多数情 ...

  8. 视频处理:帧差法、光流法和背景减除法的视频目标识别

    视频处理:帧差法.光流法和背景减除法的视频目标识别视频处理:帧差法.光流法和背景减除法的视频目标识别视频处理:帧差法.光流法和背景减除法的视频目标识别 1.调用摄像头 函数1:cv2.VideoCap ...

  9. Python实现视频运动目标检测——帧差法

    Python实现视频运动目标检测--帧差法 在许多场景中,我们需要对视频中的运动目标进行检测.而在这个过程中,帧差法是一种常用的方法.本文将详细阐述Python如何利用帧差法实现视频运动目标检测. 首 ...

  10. python识别重影验证码_python+opencv实现移动侦测(帧差法)

    本文实例为大家分享了python+opencv实现移动侦测的具体代码,供大家参考,具体内容如下 1.帧差法原理 移动侦测即是根据视频每帧或者几帧之间像素的差异,对差异值设置阈值,筛选大于阈值的像素点, ...

最新文章

  1. 第一轮通知 | 2022年中国生物物理学会肠道菌群分会年会暨“崂山论肠菌”学术论坛...
  2. 微信内置浏览器无法清除缓存问题
  3. Java-JUC(一):volatile引入
  4. 论文浅尝 - AAAI2020 | 多模态基准指导的多模态自动文摘
  5. 郁金香商业辅助教程 2016 笔记 6~10
  6. 坑了腾讯1624万!3人冒充老干妈员工诈骗腾讯 判决结果来了...
  7. 一、kafka安装下载与kafka初步应用
  8. 摩托罗拉linux专属游戏,摩托罗拉E680g Linux系统手机也可以玩游戏
  9. 转:L298N的原理图以及程序实现
  10. 微信红包封面催生暴利灰产:有人月入三十万
  11. 离散数学计算机科学与技术答案,湘潭大学计算机科学与技术刘任任版离散数学课后习题答案---第二学期--图论与组合数学...
  12. 什么是PLC的响应时间
  13. 如何申请公众号的专属微社区?
  14. 仿淘宝头像上传功能(一)——前端篇。
  15. NCRE-嵌入式系统开发工程师-操作系统知识整理
  16. 万字长文文带你了解自动驾驶重要传感器——激光雷达
  17. css的white-space属性:normal,nowrap,pre,pre-line和pre-wrap的区别?
  18. webstorm 常用插件集合
  19. Oracle 利用储存过程插入循环插入大量数据方法
  20. scada如何用oracle数据库,怎样设计SCADA系统数据库存储功能及其应用

热门文章

  1. 电脑自带蓝牙与HC-06蓝牙模块使用串口助手通信
  2. rsyslog,journalctl
  3. linux netperf,linux netperf的安装
  4. Oracle数据库基本操作(windows 本地环境)
  5. (文末福利)2021黑马Python6.5之Python环境搭建与输入输出
  6. 反爬虫策略分析及处理
  7. 组策略本地计算机策略导出,关于win10系统本地组策略备份和设置的详细步骤
  8. 计算机网络中ip子网的划分,计算机网络学习笔记(十二)IP 子网划分
  9. origin 2018安装教程与安装包
  10. android 过滤蓝光软件下载,安卓蓝光过滤器