读取视频序列 - sumpig/OpenCV GitHub Wiki
- 只需指定视频文件名即可打开视频
cv::VideoCapture capture("bike.avi");
- 如果对象已经创建,可以使用它的 open 方法
capture.open("bike.avi");
- 成功打开后,可以使用 isOpened 方法验证
capture.isOpened();
- 可以使用 get 方法并采用正确的标志来查询视频文件的有关信息,CV_CAP_PROP_FPS 可以获得帧速率,该方法总会返回一个 double 类型的数值
double r = capture.get(CV_CAP_PROP_FPS);
- 获取视频文件总帧数 CV_CAP_PROP_FRAME_COUNT
long t = static_cast<long>(capture.get(CV_CAP_PROP_FRAME_COUNT));
- set 方法,可以用 CV_CAP_PROP_POS_FRAMES 标志让视频跳到指定的帧
// 跳到第 100 帧
double position = 100.0;
capture.set(CV_CAP_PROP_POS_FRAMES, position);
- CV_CAP_PROP_POS_MSEC 以毫秒为单位指定位置
- CV_CAP_PROP_POS_AVI_RATIO 指定视频内部的想定位置 (0.0 - 1.0)
- read 方法可以按顺序访问每一帧,也可以调用重载运算符 >>
cv::Mat frame;
capture.read(frame);
capture >> frame;
- grab 方法从视频文件或捕获设备中抓取下一个帧,假如调用成功返回true
capture.grab();
- retrieve 方法解码并且返回刚刚抓取的视频帧,假如没有视频帧被捕获(相机没有连接或者视频文件中没有更多的帧)将返回false
capture.retrieve(frame);
- release 方法关闭视频文件,不是必须的,因为在 cv::VideoCapture 的析构函数中也会调用 release
- 读取摄像机,只需在 open 方法中指定一个 ID 取代原来的文件名即可,ID 为 0 表示打开默认摄像机
- 也可以装载 Web 上的视频,需要提供一个正确的网址
cv::VideoCapture capture("http://www.laganiere.name/bike.avi");
下面这个基本函数显示了视频序列中的帧:
int main() {
cv::VideoCapture capture("bike.avi");
if (!capture.isOpened()) return 1;
double rate = capture.get(CV_CAP_PROP_FPS);
int delay = 1000/rate; // 根据帧速率计算帧之间的等待时间,单位为 ms
cv::Mat frame;
cv::namedWindow("Frame");
bool stop(false);
while(!stop) {
if (!capture.read(frame)) break;
cv::imshow("Frame", frame);
if (cv::waitKey(delay) >= 0) // 通过按键可以停止,cv::waitKey() 默认返回-1,按键则返回大于0的相应的 ASCII 码
stop = true;
}
capture.release();
return 0;
}