OpenCV入门学习(五)处理视频帧

2023-11-16

opencv2+vs2010

opencv不仅可以播放视频,还可以对视频进行处理,并输出处理后的视频,本文以提取视频canny边缘为例,编写程序如下:

#include<highgui.h>
#include<opencv2/imgproc/imgproc.hpp>
void processFrame(cv::Mat& img,cv::Mat& out);
void canny(cv::Mat& img,cv::Mat& out){
 //灰度转换
 if(img.channels()==3)
  cv::cvtColor(img,out,CV_BGR2GRAY);
 //计算Canny边缘
 cv::Canny(out,out,100,200);
 //反转图像
 cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
}
class VideoProcessor{
private:
 //opencv视频捕捉对象
 cv::VideoCapture capture;
 //每帧调用的回调函数
 void(*process)(cv::Mat& , cv::Mat&);
 //确认是否调用回调函数的bool变量
 bool callIt;
 //输入窗口的名称
 std::string windowNameInput;
 //输出窗口的名称
 std::string windowNameOutput;
 //延迟
 int delay;
 //已处理的帧数
 long fnumber;
 //在该帧处停止
 long frameToStop;
 //是否停止处理
 bool stop;
public:
 VideoProcessor():callIt(true),delay(0),
  fnumber(0),stop(false),frameToStop(-1){}
//设置视频文件的名称
 bool setInput(std::string filename){
  fnumber = 0;
  //释放之前打开过的资源
  capture.release();
  //images.clear();
  //打开视频文件
  return capture.open(filename);
 }
    //创建输入窗口
 void displayInput(std::string wn){
  windowNameInput = wn;
  cv::namedWindow(windowNameInput);
 }
 //创建输出窗口
 void displayOutput(std::string wn){
  windowNameOutput = wn;
  cv::namedWindow(windowNameOutput);
 }
 //不再显示处理后的帧
 void dontDisplay(){
  cv::destroyWindow(windowNameInput);
  cv::destroyWindow(windowNameOutput);
  windowNameInput.clear();
  windowNameOutput.clear();
 }
 //设置回调函数
 void setFrameProcessor(void(*frameProcessingCallback)(cv::Mat& ,cv::Mat&)){
   process = frameProcessingCallback;
 }
 //获取并处理序列帧
 void run(){
  //当前帧
  cv::Mat frame;
  //输出帧
  cv::Mat output;
  //打开失败时
  if(!isOpened())
   return;
  stop = false;
  while(!isStopped()){
   //读取下一帧
   if(!readNextFrame(frame))
    break;
   //显示输入帧
   if(windowNameInput.length()!=0)
    cv::imshow(windowNameInput,frame);
   //调用处理函数
   if(callIt){
   //处理当前帧
    process(frame,output);
   //增加帧数
    fnumber++;
   }else{
    output = frame;
   }
   //显示输出帧
   if(windowNameOutput.length()!=0)
    cv::imshow(windowNameOutput,output);
   //引入延迟
   if(delay>=0 && cv::waitKey(delay)>=0)
    stopIt();
   //检查是否需要停止运行
   if(frameToStop>=0 && getFrameNumber()==frameToStop)
    stopIt();
  }
 }
     //停止运行
 void stopIt(){
  stop = true;
 }
 //是否已停止?
 bool isStopped(){
  return stop;
 }
 //是否开始了捕获设备?
 bool isOpened(){
  return capture.isOpened();
 }
 //设置帧间延迟
 //0意味着在每帧都等待用户按键
 //负数意味着没有延迟
 void setDelay(int d){
  delay = d;
 }
 //得到下一帧
 //可能是:视频文件或摄像头
 bool readNextFrame(cv::Mat& frame){
  return capture.read(frame);
 }
 //需要回调函数
 void callProcess(){
  callIt = true;
 }
 //不需要调用回调函数
 void dontCallProcess(){
  callIt = false;
 }
 //可以在特定的帧停止
 void stopAtFrameNo(long frame){
  frameToStop = frame;
 }
 //返回下一帧的帧数 
 long getFrameNumber(){
  //得到捕获设备的信息
  long fnumber = static_cast<long>(
  capture.get(CV_CAP_PROP_POS_FRAMES));
 return fnumber;
 }
 //获取帧率
 double getFrameRate()
 {
  double rate=static_cast<double>(capture.get(CV_CAP_PROP_FPS));
  return rate;
 }
 }; 
int main(){
//创建实例
VideoProcessor processor;
//打开视频文件
processor.setInput("../people.avi");
//声明显示窗口
processor.displayInput("Current Frame");
processor.displayOutput("Output Frame");
//以原始帧率播放视频
processor.setDelay(1000./processor.getFrameRate());
//设置处理回调函数
processor.setFrameProcessor(canny);
//开始处理过程
processor.run();
return 0;
}

原视频:
在这里插入图片描述

处理后的视频:
在这里插入图片描述

参考书目:
OpenCV3编程入门_毛星云编著_电子工业出版 10.3节
https://blog.csdn.net/In_Sunshine/article/details/51243072

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenCV入门学习(五)处理视频帧 的相关文章

随机推荐

  • nginx php 错误日志,nginx、php-fpm、php 错误日志的关系

    nginx php fpm php 三者的配置文件中都有 error log 项 指定各自错误日志的保存路径 理论上它们三者的错误应该不会重合 即 nginx error log 记录的是 nginx 进程自己的错误 php fpm err
  • Linux 帧缓冲子系统详解:LCD介绍、framebuffer驱动框架、LCD驱动源码分析

    1 LCD显示屏基础知识介绍 请看博客 嵌入式开发 S5PV210 LCD显示器 2 内核帧缓冲子系统 2 1 功能介绍 1 帧缓冲 framebuffer 是 Linux 为显示设备提供的一个接口 它把显示设备描述成一个缓冲 区 允许应用
  • 简单理解 进程 & 线程

    文章目录 线程与进程之间的区别和联系 进程 线程之间的理解 进程 进程管理 PCB 并行 并发 线程 线程与进程之间的区别和联系 进程包含线程 都是为了实现并发编程的方式 线程比进程更轻量 进程是系统分配资源的基本单位 线程是系统调度执行的
  • python:Numpy学习(二)切片合集

    前言 本文根据本人自己的学习成果总结的 内容难免产生纰漏 如有错误 望各位路过大佬指出 建议按顺序食用本文 效果更佳 文内例子均以二维数组为例 本文主要包含numpy ndarray数组的多种切片方法 在阅读本文前 请思考下面的问题 Q 假
  • 大一自学Java到毕业,学会这些内容,就可以进大厂

    我就是自学Java进的大厂 学校很普通一个不知名的二本 专业是计算机专业 不过在学校学不到什么 基本都是靠自学 我们班进一线大厂的人有6个 我就是其中一个 剩下的人大部分去考研了 下面这个学习安排就是我在大学自学的内容 就适合时间多的大学生
  • 动手学CV-目标检测入门教程6:训练与测试

    3 6 训练与测试 本文来自开源组织 DataWhale CV小组创作的目标检测入门教程 对应开源项目 动手学CV Pytorch 的第3章的内容 教程中涉及的代码也可以在项目中找到 后续会持续更新更多的优质内容 欢迎 如果使用我们教程的内
  • 《软件方法》书中自测题大全-题目全文+分卷自测

    已经根据最新版本内容更新了在线题库 以下是 软件方法 1 8章中的自测题 答案不直接给出 可访问每套题后面的自测链接或扫二维码自测 做到全对才能知道答案 知识点见 软件方法 http www umlchina com book softme
  • Latex 字母上方箭头

    字母上方右箭头 mathop A limits rightarrow A mathop A limits rightarrow A 或者 vec A
  • 一款使用 Jetbrains IDE 开发事半功倍的工具

    使用 Jetbrains 公司开发软件的小伙伴一般都用 Toolbox App 来管理自己的开发软件 这个管理工具使用起来非常舒服 包括安装 更新 还等随心所欲的回滚和降级 这大大节省了维护IDE的时间和精力 IDE 管理 随心打开任意项目
  • c++类成员初始化方式

    转载自 https blog csdn net coder xia article details 7447822 常用的初始化可能如下 1 赋值初始化 class Student public Student string in name
  • 一个主设备号是如何支持多个次设备?

    1 主次设备号 参考博客 字符设备驱动详解 主次设备号 注册 卸载字符设备驱动 创建设备节点 地址映射 2 次设备号介绍 1 在老的驱动程序里是不需要次设备号的 在老版内核中注册驱动用register chrdev 函数 只需要传入主设备号
  • 自旋锁(spinlock) 解释得经典,透彻

    自旋锁与互斥锁有点类似 只是自旋锁不会引起调用者睡眠 如果自旋锁已经被别的执行单元保持 调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁 自旋 一词就是因此而得名 由于自旋锁使用者一般保持锁时间非常短 因此选择自旋而不是睡眠是非常必
  • 解决提示“Warning File ‘CMakeFilesxxxxxx.dirprogress.make‘ has modification time 2.4 s in the future”方法

    问题描述 今天分享一个我自己之前在使用虚拟机中使用cmake进行编译连接时候产生的一个告警提示 首先看告警提示 Warning File CMakeFiles xxxxxx dir progress make has modificatio
  • SMT HT CMP SMP

    1 多线程 同时多线程 Simultaneous multithreading 简称 SMT SMT 可通过复制处理器上的结构状态 让同一个处理器上的多个线程同步执行并共享处理器的执行资源 可最大限度地实现宽发射 乱序的超标量处理 提高处理
  • 多版本node的安装与切换详细操作

    多版本node的安装与切换详细操作 安装多版本node的原因 方法一 利用nvm进行管理 NVM 简介 安装前须知 卸载已安装的nodeJS nvm 的安装与使用 node 的不同版本安装及切换 方法二 通过配置环境变量 切换node时只需
  • Spark课程设计——电影推荐系统

    题目所需数据集及相应信息描述 数据集 1 用户评分数据集ratings dat 包含了大量用户的历史评分数据 2 样本评分数据集personalRatings dat 包含了少数几个用户的个性化评分数据 这些数据反映了某个用户的个性化观影喜
  • python3 隐藏print的标准输出

    在使用python调用函数时 想将函数中的print输出禁止掉又不想改函数的代码 可以定义如下HiddenPrints类解决 class HiddenPrints def enter self self original stdout sy
  • 二、Spring IoC 容器

    IOC容器及相关概念 什么是 IOC 控制反转 把对象创建和对象之间的调用过程 交给 Spring 容器来管理 使用 IOC 的目的 为了解耦合 IOC 的底层原理 XML 解析技术 工厂模式 反射 IOC 目的 最低限度降低类与类之间的耦
  • landsat8数据下载教程

    Landsat下载地址 我们最常用的下载地址是USGShttps earthexplorer usgs gov 这是一个提供Landsat和其他卫星影像数据的官方网站 如果您还没有USGS EarthExplorer账户 请点击网站右上角的
  • OpenCV入门学习(五)处理视频帧

    opencv2 vs2010 opencv不仅可以播放视频 还可以对视频进行处理 并输出处理后的视频 本文以提取视频canny边缘为例 编写程序如下 include