首页 > 编程语言 >【C++】【OpenCV-4.9.0】播放视频

【C++】【OpenCV-4.9.0】播放视频

时间:2024-02-29 20:57:02浏览次数:21  
标签:滑块 int cap 4.9 C++ OpenCV 跟踪 include cv

相较于之前的Python下的opencv读取视频流并展示,C++下有一些不同需要配置

1、opencv\build文件夹的bin文件夹下的opencv_videoio_ffmpeg490_64.dll需要拷贝至工程文件中,或者将bin路径写入环境变量也可。(如果没有这个dll文件的话,可能会出现一直读取视频失败,即使用isOpened()返回false)。

 1 #include<iostream>
 2 #include<string>
 3 #include<opencv2/highgui/highgui.hpp>
 4 #include<opencv2/imgproc/imgproc.hpp>
 5 
 6 int main(int argc, char** argv) {
 7     cv::namedWindow("Video", cv::WINDOW_AUTOSIZE);
 8     cv::VideoCapture cap;
 9     cap.open(argv[1]);
10     cv::Mat frame;
11     if (!cap.isOpened()) std::cout << "Failed!" << std::endl;
12     for (;;) {
13         cap >> frame;
14         if (frame.empty()) break;
15         std::cout << "OK" << std::endl;
16         cv::imshow("Video", frame);
17         if (cv::waitKey(33) >= 0) break;
18     }
19     return 0;
20 }

 上述代码只是简单的播放视频,我们还可以通过添加跟踪条和监听按键来完成跳转和暂停功能:

1、cv::trackbar()来创建进度条

2、cv::VideoCapture::get()来获取实时帧率信息

3、cv::setTrackbarPos()实时更新进度条进度

4、cv::VideoCapture::set()调整视频进度

关于回调函数的调用,每次经过setTrackbarPos()时都会去调用一遍回调函数,并将第三个参数传给回调函数中的int形参(current_pos会传给pos)

 1 #include <iostream>
 2 #include <fstream>
 3 #include <opencv2/highgui/highgui.hpp>
 4 #include <opencv2/imgproc/imgproc.hpp>
 5 using namespace std;
 6 
 7 // 标记进度条位置
 8 int g_slider_position = 0;
 9 // 设置播放状态
10 int g_run = 1, g_dotset = 0;
11 cv::VideoCapture g_cap;
12 
13 void onTrackbarSlide(int pos, void*) {
14     g_cap.set(cv::CAP_PROP_POS_FRAMES, pos);
15     // 当希望触发回调函数后自动播放时则设置为1,否则可直接注释该行或者置0
16     g_run = 0;
17 }
18 
19 int main(int argc, char** argv) {
20     cv::namedWindow("Video", cv::WINDOW_AUTOSIZE);
21     g_cap.open(argv[1]);
22     // 读取帧率
23     int frames = (int)g_cap.get(cv::CAP_PROP_FRAME_COUNT);
24     // 读取宽度
25     int tmpw = (int)g_cap.get(cv::CAP_PROP_FRAME_WIDTH);
26     // 读取高度
27     int tmph = (int)g_cap.get(cv::CAP_PROP_FRAME_HEIGHT);
28     cout << "Video has " << frames << "frames of dimensions("
29         << tmpw << ", " << tmph << ")." << endl;
30     // 创建进度条
31     cv::createTrackbar("Position", "Video", &g_slider_position, frames,
32         onTrackbarSlide);
33     cv::Mat frame;
34     for (;;) {
35         if (g_run != 0) {
36             g_cap >> frame;
37             if (frame.empty()) break;
38             int current_pos = (int)g_cap.get(cv::CAP_PROP_POS_FRAMES);
39             cout << "Back call" << endl;
40             cv::setTrackbarPos("Position", "Video", current_pos);
41             cv::imshow("Video", frame);
42 
43             g_run = -1;
44         }
45         char c = (char)cv::waitKey(10);
46         if (c == 's') {
47             g_run = 0;
48             cout << "Single step, run = " << g_run << endl;
49         }
50         if (c == 'r') {
51             g_run = -1;
52             cout << "Run mode, run = " << g_run << endl;
53         }
54         if (c == 27)
55             break;
56 
57     }
58 
59     return 0;
60 }

◆ createTrackbar()

int cv::createTrackbar(const String&  trackbarname,

          const String&  winname,

          int *       value,

          int       count,

          TrackbarCallback onChange = 0,

          void *       userdata = 0

          )

创建跟踪栏并将其附加到指定的窗口。

函数 createTrackbar 创建具有指定名称和范围的跟踪栏(滑块或范围控件),将变量值指定为与跟踪栏同步的位置,并指定要在跟踪栏位置更改时调用的回调函数 onChange。创建的跟踪栏显示在指定的窗口 winname 中。

Parameters

  trackbarname  创建的跟踪栏的名称

  winname    将用作所创建跟踪栏的父级的窗口的名称

  value       指向整数变量的可选指针,其值反映滑块的位置。创建时,滑块位置由此变量定义

  count       滑块的最大位置。最小位置始终为 0

  onChange     指向每次滑块更改位置时要调用的函数的指针。这个函数应该被原型化为 void Foo(int,void*);,其中第一个参数是跟踪栏位置,第二个参数是用户数据(请参阅下一个参数)。如果回调为 NULL 指针,则不调用回调,只更新值

  userdata     按原样传递给回调的用户数据。它可用于在不使用全局变量的情况下处理跟踪栏事件

标签:滑块,int,cap,4.9,C++,OpenCV,跟踪,include,cv
From: https://www.cnblogs.com/vangoghpeng/p/18041339

相关文章

  • C++位运算函数总结
    __builtin超实用位运算函数总结①后导0(__builtin_ctz())#include<bits/stdc++.h>usingnamespacestd;intmain(){ cout<<__builtin_ctz(8)<<endl;//ans=3because8=0b1000 return0;}②前导0(__builtin_clz())#include<bits/stdc++.h&g......
  • 【C++】Mat和Pat希望邀请他们的朋友来参加派对。他们要编写一个程序完成下面的任务。
    Mat和Pat希望邀请他们的朋友来参加派对。他们要编写一个程序完成下面的任务。让Mat输入他朋友的姓名列表。姓名存储在一个容器中,然后按排列后的顺序显示出来。让Pat输入她朋友的姓名列表。姓名存储在另一个容器中,然后按排列后的顺序显示出来。创建第三个容器,将两个列表合并,删除重......
  • 【C++】相对于数组,在链表中添加和删除元素更容易,但排序速度更慢。这就引出了一种可能
    相对于数组,在链表中添加和删除元素更容易,但排序速度更慢。这就引出了一种可能性:相对于使用链表算法进行排序,将链表复制到数组中,对数组进行排序,再将排序后的结果复制到链表中的速度可能更快;但这也可能占用更多的内存。请使用如下方法检验上述假设。a.创建大型vector<int>对象vi0,并......
  • C++ 多线程笔记1 线程的创建
    C++多线程笔记1线程的创建里面代码会用到的头文件#include<iostream>#include<string>#include<memory>#include<thread>#include<vector>#include<stdlib.h>#include<cmath>#include<chrono>#include<ctime>入门例子vo......
  • c++ queue在多线程中的使用
    queue队列,先进先出。多线程的一种使用案例:生产者每3spush一个元素消费者每5s才能pop一个元素(队首)那么,2个消费者就可以及时地消耗掉push的元素。#include<iostream>#include<thread>#include<mutex>#include<queue>std::queue<int>m_queue;std::mutexm_mutex;std:......
  • [没啥用科技] C++ 分数类
    虽然说用的是结构体,但已经实现了同类型加减乘除和分数与整型的加减乘除。写的有点难看,并伴有大常数,以后来改。#include<bits/stdc++.h>#include<bits/extc++.h>#definelllonglong#defineldblongdouble#definem_p(a,b)make_pair(a,b)usingnamespacestd;using......
  • c++ primer ch2笔记
    ch22.1基本内置类型C++基本内置类型void算术类型整形(包括字符,bool)浮点型最小尺寸:整形尺寸大小受编译器影响,但是至少会保证一个最小尺寸,int最小尺寸2字节相互关系:int至少和一个short一样大无符号类型:unsignedint、unsignedlong类型转换规则:布......
  • rust与python/c++语法区别
    if/matchpubfnanimal_habitat(animal:&str)->&'staticstr{letid=ifanimal=="crab"{//id等于(或拥有)了一个匿名函数的返回值1}elseifanimal=="gopher"{2}elseifanimal=="snake"......
  • C++的异常处理究竟有多慢?
    我们能在各处看到“C++的异常很慢,不要用”这样的言论,不过很少有人告诉你,C++的异常到底有多慢,以及它为什么这么慢。本文会详细介绍C++在抛出以及捕获异常时,代码到底做了什么,以及我们使用C++异常到底付出了多少代价。抛出异常要了解异常处理到底做了什么,我们需要深入到汇编语言来......
  • 通过前向声明解决C++中两个头文件互相引用的问题
    在C++中,当两个头文件互相引用时,可以通过前向声明来避免直接的#include依赖,从而解决循环依赖的问题。前向声明是在一个头文件中声明另一个头文件中的类或类型的名称,而不包括其具体的实现细节。这样,每个头文件只依赖对方的声明,而不需要依赖对方的定义,从而打破了循环依赖。以下是如......