《opencv实用探索·十四》VideoCapture播放视频和视像头调用

1、VideoCapture播放视频

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	// 定义相关VideoCapture对象
	VideoCapture capture;
	// 打开视频文件
	capture.open("1.avi");
	//  判断视频流读取是否正确
	if (!capture.isOpened())
	{
		std::cout << "fail to open video!" << std::endl;
		return -1;
	}
	// 获取视频相关信息-帧像素宽高 
	int  frameWidth = capture.get(cv::CAP_PROP_FRAME_WIDTH);
	int  frameHeight = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
	std::cout << "视频中图像的宽度为:" << frameWidth << std::endl;
	std::cout << "视频中图像的高度为: " << frameHeight << std::endl;

	// 获取视频相关信息-帧率
	double FrameRate = capture.get(cv::CAP_PROP_FPS);
	std::cout << "视频帧率为:" << FrameRate << std::endl;

	// 获取视频相关信息-帧数
	long nTotalFrame = capture.get(cv::CAP_PROP_FRAME_COUNT);
	std::cout << "视频总帧数为:" << nTotalFrame << std::endl;

	// 如果视频读取成功则创建视频流

	cv::Mat frameImg;
	long nCount = 1;
	while (true)
	{
		capture >> frameImg;//获取当前帧图像

		// 显示当前帧
		if (!frameImg.empty())
		{
			imshow("frameImg", frameImg);
			if (char(waitKey(int(1000 / FrameRate)) == 'q')) // 按下键盘上q键退出
				break;
		}
		else
		{
			break;
		}

		nCount++;
	}
	// 视频释放
	capture.release();
	return 0;
}

waitKey(int(1000 / FrameRate)) 是用于在每一帧显示后等待一定时间的语句。它的作用是在视频播放时限制帧率,以使视频以正常速度播放。

具体来说:

FrameRate 是视频的帧率,表示每秒播放的帧数。

1000 / FrameRate 计算出每一帧需要显示的时间(以毫秒为单位),即每帧之间的间隔时间。

waitKey 是一个 OpenCV 函数,它等待用户在键盘上按键的时间。如果在指定的时间内按下键盘上的键,它会返回按键的 ASCII 值,否则返回 -1。

因此,waitKey(int(1000 / FrameRate)) 的作用是等待足够的时间,以保持视频的实际帧率接近指定的 FrameRate。这有助于以正常速度播放视频,而不是以计算机能够处理的最大速度。

如果把waitKey 换成Sleep延时会导致视频卡死,因为Sleep仅仅只是简单的延时,延时期间直接阻塞当前线程,而waitKey在延时的同时能够使当前线程保持持续的响应,类似Qt中QCoreApplication::processEvents();防止界面假死操作。

当我们等待的时间小于int(1000 / FrameRate)能实现视频快放的效果,当我们等待的时间大于int(1000 / FrameRate)能实现视频慢放的效果。

2、VideoCapture调用摄像头

cpp 复制代码
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
	// 定义相关VideoCapture对象
	VideoCapture capture(0);

	//  判断摄像头是否打开
	if (!capture.isOpened())
	{
		std::cout << "fail to open video!" << std::endl;
		return -1;
	}

	// 获取摄像头相关信息-帧像素宽高 
	int  frameWidth = capture.get(cv::CAP_PROP_FRAME_WIDTH);
	int  frameHeight = capture.get(cv::CAP_PROP_FRAME_HEIGHT);
	std::cout << "摄像头中图像的宽度为:" << frameWidth << std::endl;
	std::cout << "摄像头中图像的高度为: " << frameHeight << std::endl;

	// 获取摄像头相关信息-帧率
	double FrameRate = capture.get(cv::CAP_PROP_FPS);
	std::cout << "摄像头帧率为:" << FrameRate << std::endl;

	// 如果摄像头打开成功则创建视频流
	cv::Mat frameImg;
	long nCount = 1;
	while (true)
	{
		capture >> frameImg;//获取当前帧图像

		// 显示当前帧
		if (!frameImg.empty())
		{
			imshow("frameImg", frameImg);
			if (char(waitKey(30) == 'q')) // 按下键盘上q键退出
				break;
		}
		else
		{
			break;
		}

		nCount++;
	}
	// capture释放
	capture.release();
	return 0;
}

上面代码中获取的摄像头的帧率为0,可能的远因如下:

摄像头不支持帧率查询:

不是所有的摄像头都支持通过 cv::CAP_PROP_FPS 查询帧率。在这种情况下,OpenCV 可能无法正确获取帧率信息,返回0。

帧率信息尚未初始化:

在有些摄像头中,帧率信息可能在摄像头开始捕获帧之前不可用。在你的代码中,你可以尝试在开始捕获帧之后再获取帧率信息。

摄像头不支持固定帧率:

有些摄像头可能不以固定的帧率工作,因此 OpenCV 无法准确地获取帧率信息。

如果无法获取摄像头的帧率,那么waitKey需要设置一个固定的等待时间,一般为30Ms

相关推荐
Shockang5 小时前
AI 智能体安全沙盒实战
人工智能
yuhulkjv3356 小时前
Claude表格复制到word不再崩溃,AI导出鸭批量导出+格式无损一键搞定
人工智能·ai·c#·word·ai导出鸭
大明者省7 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
抱抱宝7 小时前
Agent-study项目教程(03):手写 Mini-ReAct Agent(不依赖框架)
javascript·人工智能·gpt·react.js·prompt·agent
抱抱宝8 小时前
大模型应用开发教程08 | 构建完整 RAG 应用(Chroma/FAISS 实战)
人工智能·gpt·prompt·agent
美团技术团队8 小时前
KDD‘26 美团学术论文精选及KDD Cup‘26 DataAgents赛道冠军思路解读
人工智能
AKAMAI8 小时前
当AI模型超出存储增长时
人工智能·云计算
科技绘图8 小时前
快鲸GEO vs 传统AI搜索优化:全链路自动化与高效内容生产在转化闭环上的对比
数据库·人工智能·自动化
DS随心转小程序8 小时前
ChatGPT 文字怎么转为 word?解析各类转换方案,AI 导出鸭成为高效文档转换新选择
人工智能·chatgpt·word·豆包·deepseek·ai导出鸭
乌恩大侠9 小时前
【AI-RAN】硬件产品:DELL 前传交换机
人工智能·spark·aerial·o-ru·ai-ran