zoukankan      html  css  js  c++  java
  • OpenCV 入门示例之三:AVI 视频播放控制

    前言

      在前文中给出了一个非常简短的视频播放程序,但它没有实现常规视频播放器中的播放滚动条功能,本文对此视频播放器程序加以改进,实现此功能。

    滚动条的实现思路

      滚动条的功能实质上就是从一帧跳跃到另外一帧,它的实现框架大致是这样的:

      1. 首先要定义一个全局变量,在每次滚动条位置发生改变时将新的位置记录下来。

      2. 然后定义一个回调函数 ,这个回调函数会在滚动条位置发生改变时自动执行。本文的程序中,回调函数具体的作用就是把程序的当前帧序更新为 1 中获取到的新的帧序。

      3. 获取当前的总帧数。

      4. 以 2 和 3 中获取到的结果等信息为参数,创建一个滚动条。

      至此,滚动条功能就创建好了,别忘了,本文程序可是要求滚动条随着视频的播放而自动推进的。

    代码示例

     1 // 此头文件包含图像IO函数的声明
     2 #include "highgui.h"
     3 // 此头文件包含基本的图像处理函数和高级计算机视觉算法
     4 #include "cv.h"
     5 
     6 // 滚动条初始位置
     7 int g_slider_position = 0;
     8 // 视频结构体
     9 CvCapture * g_capture = NULL;
    10 // 当前帧序
    11 int frameCur = 0;
    12 
    13 void onTrackbarSlide (int pos) {
    14 
    15     // 设置视频结构体的相关属性
    16     cvSetCaptureProperty (
    17         g_capture, // 视频结构体
    18         CV_CAP_PROP_POS_FRAMES, // 以帧为单位计量
    19         pos // 新的位置
    20     );
    21     // 更新当前帧序
    22     frameCur = pos;
    23 }
    24 
    25 int main (void) {
    26 
    27     // 定义一个窗口来播放视频
    28     cvNamedWindow ("示例", CV_WINDOW_AUTOSIZE );
    29 
    30     // 将 D 盘目录下名为" 1.avi "的视频加载至内存并获得一个指向该视频内存块的指针,将它返回给 g_capture
    31     // 该指针所指向的结构包含了此视频的当前播放帧序
    32     g_capture = cvCreateFileCapture ("D:\1.avi");
    33 
    34     // 获取视频文件的总帧数
    35     // 第一个参数为视频结构体;第二个参数为需要获取的属性标识( 本例为总帧数 )
    36     int frames = (int) cvGetCaptureProperty (
    37                     g_capture,
    38                     CV_CAP_PROP_FRAME_COUNT 
    39                 );
    40 
    41     // 创建滚动条
    42     // 第一个参数为滚动条标题;第二个参数为滚动条所在窗口名;第三个参数为初始滑块位置
    43     // 第四个参数为滑块总帧数;第五个参数为当滚动条发生改变时要调用的回调函数。
    44     if (frames != 0) {
    45         cvCreateTrackbar (
    46             "位置",
    47             "示例",
    48             &g_slider_position,
    49             frames,
    50             onTrackbarSlide
    51         );
    52     }
    53 
    54     // 定义一个图像指针来指向各帧图像
    55     IplImage *frame;
    56 
    57     while (1) {
    58 
    59         // 获取视频最新的帧图。这个帧图是存放在视频内存块里的,因此,程序结束时只释放 capture 所指向的内存块就够了。
    60         frame = cvQueryFrame (g_capture);
    61 
    62         // 更新滚动条位置
    63         cvSetTrackbarPos(
    64             "位置",    // 滚动条所在窗口
    65             "示例",    // 滚动条标题
    66             frameCur++    // 滚动条位置
    67         );
    68 
    69         // 读取帧失败则退出程序
    70         if (!frame) break;
    71 
    72         // 显示最新获取到的帧图
    73         cvShowImage ("示例", frame);
    74 
    75         // 用户键入ESC后退出循环,键入其他按键播放下一帧,什么都不按则 33 毫秒之后自动播放下一帧。
    76         char c = cvWaitKey(33);
    77         if (c==27) break;
    78     };
    79 
    80     // 释放空间
    81     cvReleaseCapture (&g_capture);
    82     cvDestroyWindow ("示例");
    83 }

    运行测试

      1. 将格式为 avi 的测试视频拷贝到 D 盘,命名为 "1.avi"。

      2. 运行结果:

      

      3. 可以看到该视频播放程序有了滚动条,且滚动条随着视频的播放而自动推进。

  • 相关阅读:
    Oracle查询数据表结构/字段/类型/大小
    Oracle 如何修改列的数据类型
    数组声明和使用要点
    关于转发和重定向的路径问题!
    Java高级架构师(一)第29节:完成下订单和修改库存的功能
    Java高级架构师(一)第28节:Index、商品详细页和购物车
    Java高级架构师(一)第27节:实现index功能的开发
    《深入理解Spark-核心思想与源码分析》(三)第三章SparkContext的初始化
    《深入理解Spark-核心思想与源码分析》(二)第二章Spark设计理念和基本架构
    《深入理解Spark-核心思想与源码分析》(一)总体规划和第一章环境准备
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3720550.html
Copyright © 2011-2022 走看看