本节介绍基于OpenCV HighGUI编写视频播放器的写法,主要实现播放进度条、鼠标控制播放暂停等功能。此处给出思路和许多功能模块的调用方法,完整代码可以在恰当的时机放出。
使用OpenCV处理视频的基本模板
以下代码是大家常用的OpenCV打开电脑摄像头的操作,本文将在假设大家学会以下基本操作的基础上展开。
#include<opencv2\highgui\highgui.hpp>
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
VideoCapture cap;
cap.open(0); //打开摄像头
if (!cap.isOpened())
return -1;
Mat frame;
while (1)
{
cap >> frame;//等价于cap.read(frame);
if (frame.empty())
break;
imshow("video", frame);
if (waitKey(20) > 0)//按下任意键退出摄像头 因电脑环境而异,有的电脑可能会出现一闪而过的情况
break;
}
cap.release();
destroyAllWindows();//关闭所有窗口
return 0;
}
若要打开电脑上已有视频,只需要改动一个地方:
cap.open(0); //打开摄像头
//改成视频路径即可,注意Windows下反斜杠要转义
cap.open("C:\\Users\\xxx\\1.mp4");
实现视频播放与暂停
这里我们主要捕捉鼠标单击事件,所以可以新建一个全局变量表示播放/暂停状态,鼠标单击事件的回调函数修改此变量。
使用以下代码绑定鼠标事件到窗体
setMouseCallback(windows_name, on_mouse_event, NULL);//第二个参数是回调函数句柄,第三个参数是向回调函数传递的参数指针,不用的话可以设置NULL
回调函数可以这样写。这里我们只关注鼠标单击键位情况,不关心单击位置等信息,所以说哪些参数也没有使用
void on_mouse_event(int event, int x, int y, int flags, void* param) {
if (event == 1) {
if (is_play == 1) {
is_play = 0;
}
else {
is_play = 1;
}
}
}
将视频播放状态与帧的更新相联系,十分巧妙
if (is_play == 1) {
cap >> frame;
}
实现视频进度条
对视频进度的调整,我们可以使用VideoCapture对象的set方法设置下一帧,get方法获取当前播放帧等。
首先我们获取最大帧数,作为进度条最大值
int max_frame = cap.get(CAP_PROP_FRAME_COUNT);//获取最大帧数
创建一个进度条 关于进度条基础知识可以看这里
createTrackbar(progressBar_name, windows_name, &video_progress, max_frame, on_progress_change, &cap);
在播放过程中恰当位置更新进度条
setTrackbarPos(progressBar_name, windows_name, cap.get(CAP_PROP_POS_FRAMES));
设置进度条更新时的回调函数
void on_progress_change(int pos, void* cap) {
VideoCapture this_cap = *(VideoCapture*) cap;
this_cap.set(CAP_PROP_POS_FRAMES, pos);
return;
}
恰当组合起来就好啦
其他问题
当然还有许多可以优化的地方,比如播放速率问题,这个可以获取视频帧速率来计算延时。