OpenCV读取视频文件

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;

/*
int main(int argc, char* argv[])
{
CvCapture* capture;
IplImage* frame;

capture = cvCaptureFromFile("E:/Videos/launch1.avi"); //绝对路径

while (1)
{
frame = cvQueryFrame(capture);
if (!frame)
break;
cvShowImage("Video", frame);
char c = cvWaitKey(10); //每一帧图像显示后,等待10毫秒
if (c == 27) //按下ESC键退出,ESC,ASCII==27
break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Video");
}*/

/* way2
int main(int argc, char** argv)
{
//========================================================
// CvCapture 是一个结构体,用来保存图像捕获所需要的信息。
// opencv提供两种方式从外部捕获图像,一种是从摄像头中,一种
// 是通过解码视频得到图像。两种方式都必须从第一帧开始一帧一帧
// 的按顺序获取,因此每获取一帧后都要保存相应的状态和参数。
// 比如从视频文件中获取,需要保存视频文件的文件名,相应的******
// 类型,下一次如果要获取将需要解码哪一帧等。 这些信息都保存在
// CvCapture结构中,每获取一帧后,这些信息都将被更新,获取下一帧
// 需要将新信息传给获取的api接口
//=======================================================
CvCapture* capture = 0;
//===========================================================
// IplImage 是结构体类型,用来保存一帧图像的信息,也就是一帧
// 图像的所有像素值构成的一个矩阵
//===========================================================
IplImage *frame, *frame_copy = 0;

// 创建一个窗口,用“result”作为窗口的标识符
cvNamedWindow("result", 1);

// ==========================================
// 初始化一个视频捕获操作。
// 告诉底层的捕获api我想从 Capture1.avi中捕获图片,
// 底层api将检测并选择相应的******并做好准备工作
//==============================================

//capture = cvCaptureFromFile("c://Capture1.avi") //
capture = cvCaptureFromFile("E:/Videos/launch1.avi");

// 如果 初始化失败,那么capture为空指针,程序停止,
// 否则进入捕获循环
if (capture)
{
// 捕获循环
for (;;)
{
// 调用cvGrabFrame,让底层api解码一帧图像
// 如果解码失败,就退出循环
// 如果成功,解码的图像保存在底层api的缓存中
if (!cvGrabFrame(capture))
break;

// 将解码得到图像信息从缓存中转换成IplImage格式放在frame中
frame = cvRetrieveFrame(capture);

// 如果获取缓存或转换失败,则退出循环
if (!frame)
break;

// 将frame中的图像信息在窗口result中显示
cvShowImage("result", frame);

// 暂停一会儿,让你看一下图像
// Sleep(66.9);
waitKey(10);

// 如果你敲了键盘,就退出程序,否则继续捕获下一帧
if (cvWaitKey(10) >= 0)
break;
}

// 退出程序之前要清理一下堆栈中的内存,免得内存泄露
//cvReleaseImage( &frame );注意不需要这句,因为frame是从视频中捕获的,没有单独分配内存,无需释放,当capture 释放的时候frame自然就释放了。

// 退出之前结束底层api的捕获操作,免得它们占着茅坑不拉屎
// 比如会使得别的程序无法访问已经被它们打开的文件
cvReleaseCapture(&capture);
}
cvDestroyWindow("result");
return 0;
}
*/

/*
//way3 读取指定的帧数
int main()
{
//打开视频文件:其实就是建立一个VideoCapture结构
VideoCapture capture("E:/Videos/launch1.avi"); //注意路径不同的表示
//检测是否正常打开:成功打开时,isOpened返回ture
if (!capture.isOpened())
cout << "fail to open!" << endl;
//获取整个帧数
long totalFrameNumber = capture.get(CV_CAP_PROP_FRAME_COUNT);
cout << "整个视频共" << totalFrameNumber << "帧" << endl;

//设置开始帧()
long frameToStart = 0; //
capture.set(CV_CAP_PROP_POS_FRAMES, frameToStart);
cout << "从第" << frameToStart << "帧开始读" << endl;

//设置结束帧
int frameToStop = 100; //

if (frameToStop < frameToStart)
{
cout << "结束帧小于开始帧,程序错误,即将退出!" << endl;
return -1;
}
else
{
cout << "结束帧为:第" << frameToStop << "帧" << endl;
}

//获取帧率
double rate = capture.get(CV_CAP_PROP_FPS);
cout << "帧率为:" << rate << endl;

//定义一个用来控制读取视频循环结束的变量
bool stop = false;
//承载每一帧的图像
Mat frame;
//显示每一帧的窗口
//namedWindow("Extracted frame");
//两帧间的间隔时间:
int delay = 1000 / rate;

//利用while循环读取帧
//currentFrame是在循环体中控制读取到指定的帧后循环结束的变量
long currentFrame = frameToStart;

//滤波器的核
int kernel_size = 3;
Mat kernel = Mat::ones(kernel_size, kernel_size, CV_32F) / (float)(kernel_size*kernel_size);

while (!stop)
{
//读取下一帧
if (!capture.read(frame))
{
cout << "读取视频失败" << endl;
return -1;
}

//这里加滤波程序
imshow("Extracted frame", frame);
filter2D(frame, frame, -1, kernel);

imshow("after filter", frame);
//cout << "正在读取第" << currentFrame << "帧" << endl;
//waitKey(int delay=0)当delay ≤ 0时会永远等待;当delay>0时会等待delay毫秒
//当时间结束前没有按键按下时,返回值为-1;否则返回按键

int c = waitKey(delay);
//按下ESC或者到达指定的结束帧后退出读取视频
if ((char)c == 27 || currentFrame > frameToStop)
{
stop = true;
}
//按下按键后会停留在当前帧,等待下一次按键
if (c >= 0)
{
waitKey(0);
}
currentFrame++;
}
//关闭视频文件
capture.release();
waitKey(0);
return 0;
} */

//way4, 读取视频文件,并显示进度
//初始化进度条的位置
int g_slider_position = 0;
CvCapture* g_capture = NULL;

//进度条的回调函数,播放进度控制
void onTrackbarSlide(int pos)
{
cvSetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES, pos);//设置视频
}

int main(int argc, char* argv[])
{
//创建播放窗口
cvNamedWindow("Window Name", CV_WINDOW_AUTOSIZE);
//捕获视频
g_capture = cvCreateFileCapture("E:/Videos/launch1.avi");
//获取视频的帧数
int frames = (int)cvGetCaptureProperty(g_capture, CV_CAP_PROP_FRAME_COUNT);
//建立进度条
if (frames != 0)
{
cvCreateTrackbar("Trackbar Name", "Window Name", &g_slider_position, frames, onTrackbarSlide);
}
//捕获、播放视频
IplImage* frame;
while (1)
{
frame = cvQueryFrame(g_capture);
if (!frame) break;
//获取视频播放位置
int trapos = (int)cvGetCaptureProperty(g_capture, CV_CAP_PROP_POS_FRAMES);
//设置进度条位置,使其和视频播放同步
cvSetTrackbarPos("Trackbar Name", "Window Name", trapos);
//播放视频
cvShowImage("Window Name", frame);
//等待按键
char c = cvWaitKey(33);
if (c == 27) break;
}
//释放资源
cvReleaseCapture(&g_capture);
cvDestroyWindow("Window Name");
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值