今天学习了opencv的HighGUI的内容
总结了两个视频读写demo以备以后进行视频处理和识别用
demo1 视频的读取和写入
按顺序读取视频的每一帧。对于读取的每一帧图像,显示在窗口中,然后转化为灰度图像输出到指定的文件中。
运行期间可以按ESC键退出。
还可以用鼠标调整滚动条来动态改变视频的播放位置。滚动条的位置≈想要播放的帧在整个视频中的位置
比如将滚动条调整到如下图所示位置,直接将视频跳转到视频总长度一半的位置开始播放
滚动条的位置≈想要播放的帧在整个视频中的位置 这里之所以是“约等于”,是因为opencv采用的帧定位的函数默认使用的是关键帧的定位方式,导致视频跳转的位置并不准确。
具体可以参见SetCaptureProperty定位不准的原因
另外有个容易出错的地方,创建视频写入器的命令:CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);
最后有个参数是0,表示输出的视频文件是灰度的。如果不设置,默认的参数取值为1,代表输出的视频文件是彩色的。如果此时将图像转换成灰度图后输出。运行视频文件是系统会提示错误。
对于这一点的描述可以参见opencv彩色图像转灰度图像失败的原因
demo1的源代码如下:
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
// 使用标准命名空间
using namespace std;
// 初始化进度条的位置
int g_slider_position1 = 0;
//初始化视频捕获器
CvCapture* g_capture1 = NULL;
// 定义回调函数用于播放进度的控制
void onTrackbarSlide1( int pos1 )
{
cvSetCaptureProperty( g_capture1, CV_CAP_PROP_POS_FRAMES, pos1 );
}
int main(int argc, char** argv )
{
// 建立播放窗口
cvNamedWindow( "Video Test 1", CV_WINDOW_AUTOSIZE );
// 捕捉视频文件
char video1[] = "yssh.avi";
//创建指定视频文件的捕获器
g_capture1 = cvCreateFileCapture( video1 );
// 读取视频文件的总帧数并显示
int frames1 = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );
cout << "总帧数 = " << frames1 << endl;
// 读取视频文件每秒显示帧数信息
double fps1 = cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );
cout << "fps1 = " << fps1 << endl;
//读取视频文件每帧图像大小信息
CvSize size1 = cvSize(
(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));
// 建立进度条
if( frames1 != 0 )
cvCreateTrackbar(
"Position",
"Video Test 1",
&g_slider_position1,
frames1,
onTrackbarSlide1
);
// 创建 VideoWriter
char out1[] = "out1.avi";
//CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('M','J','P','G'), fps1, size1,0);
//创建视频写入器
CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);
// 记录视频的某一帧
IplImage* frame1;
//记录视频某一帧转换后的灰度图像
IplImage* gray1 = cvCreateImage(size1, 8, 1);
//读取并播放视频,直至播放结束/主动退出
while( true )
{
// 获取源文件的一帧画面
frame1 = cvQueryFrame( g_capture1 );
if( !frame1 ) break;
//显示这一帧
cvShowImage( "Video Test 1", frame1 );
// 将当前帧转换为灰度图像
cvCvtColor(frame1 ,gray1, CV_RGB2GRAY);
// 保存:将当前帧(灰度图)写入到目标视频文件
cvWriteFrame( wrVideo1, gray1 );
// 若按下 ESC 键,则退出程序
char c = cvWaitKey(33);
if( c == 27 ) break;
}
// 释放内存,关闭窗口
cvReleaseCapture( &g_capture1 );
cvReleaseVideoWriter( &wrVideo1 );
cvDestroyWindow( "Video Test 1" );
return 0;
}
demo2 视频等间隔采样
程序按顺序读取视频的每一帧,对于满足固定间隔的帧图像,显示并输入,不满足的直接跳过。
这个demo可以用于等间隔的从视频中抽取图像,以备以后进行视频处理和识别用
demo2的源代码如下:
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
// 使用标准命名空间
using namespace std;
//初始化视频捕获器
CvCapture* g_capture1 = NULL;
int main(int argc, char** argv )
{
// 建立播放窗口
cvNamedWindow( "Video Test 1", CV_WINDOW_AUTOSIZE );
// 捕捉视频文件
char video1[] = "yssh.avi";
//创建指定视频文件的捕获器
g_capture1 = cvCreateFileCapture( video1 );
// 读取视频文件的总帧数并显示
int TotalFrames = (int) cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FRAME_COUNT );
cout << "总帧数 = " << TotalFrames << endl;
// 读取视频文件每秒显示帧数信息
double fps1 = cvGetCaptureProperty( g_capture1, CV_CAP_PROP_FPS );
cout << "fps1 = " << fps1 << endl;
//读取视频文件每帧图像大小信息
CvSize size1 = cvSize(
(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty(g_capture1, CV_CAP_PROP_FRAME_HEIGHT));
//CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('M','J','P','G'), fps1, size1,0);
//创建视频写入器VideoWriter
char out1[] = "IntervalOutput.avi";
CvVideoWriter* wrVideo1 = cvCreateVideoWriter(out1, CV_FOURCC('X','V','I','D'), fps1, size1,0);
// 记录视频的某一帧
IplImage* frame1;
//记录视频某一帧转换后的灰度图像
IplImage* gray1 = cvCreateImage(size1, 8, 1);
int position=0;
int interval=10; //这里指定一个抽取视频间隔
//读取并播放视频,直至播放结束/主动退出
while( true )
{
// 先获取源文件的一帧画面
frame1 = cvQueryFrame( g_capture1 );
if( !frame1 ) //视频读取完毕
break;
position=(int)cvGetCaptureProperty( g_capture1, CV_CAP_PROP_POS_FRAMES);
if(position%interval!=0)
continue;
//显示这一帧
cvShowImage( "Video Test 1", frame1 );
// 将当前帧转换为灰度图像
cvCvtColor(frame1 ,gray1, CV_RGB2GRAY);
// 保存:将当前帧(灰度图)写入到目标视频文件
cvWriteFrame( wrVideo1, gray1 );
// 若按下 ESC 键,则退出程序
char c = cvWaitKey(33);
if( c == 27 ) break;
}
// 释放内存,关闭窗口
cvReleaseCapture( &g_capture1 );
cvReleaseVideoWriter( &wrVideo1 );
cvDestroyWindow( "Video Test 1" );
return 0;
}