当前位置: 首页 > news >正文

OpenCV VideoCapture 类

OpenCV 0630学习笔记

学习内容:

imread() 读取图片

namedWindow() 创建窗口

imshow() 显示图片

imwrite() 保存图片

destroyAllWindows() 销毁窗口

waitKey() 等待

Mat 图像属性

1)empty() 判断文件读取是否为空

2)rows 获取图像行数(高度)

3)cols 获取图像列数(长度)

4)chanels() 获取图像通道数

5)depth() 获取图像位深度

OpenCV VideoCapture 类

1)open() 打开视频或摄像头

2)isOpened() 判断读取视频文件是否正确,正确返回true

3)release() 关闭视频流文件

4)get() 返回指定视频类的相关参数信息

为了方便期间,我采用了类的头文件,在类中编写方法体,主函数中进行不同功能的调用。

1.创建新项目并配置OpenCV开发环境

配置包含目录

配置库目录

Debug带d

Release 不带d

2.案例 ① 读取摄像头/视频

案例①:读取摄像头,指定按键esc(ascii码值为27)退出浏览

1.创建并编辑QuickDemo.h

#pragma once #include<opencv2/opencv.hpp> #include<iostream> using namespace cv; using namespace std; class QuickDemo { public:void OpenCamera1(); };

2.创建并编辑QuickDemo.cpp

#include "QuickDemo.h" /// <summary> /// 案例①:读取摄像头,指定按键esc(ascii码值为27)退出浏览 /// </summary> void QuickDemo::OpenCamera1() { //1.创建视频捕获对象 VideoCapture cap; //打开默认摄像头,参数0代表本机摄像头 cap.open(0); //2.判断是否打开成功 isOpened() if (!cap.isOpened()) { cout << "摄像头打开失败!" << endl; return; } cout << "打开本地摄像头" << endl; //3.创建图片数据对象 Mat frame; while (true) { //读取一帧画面 cap.read(frame); //读到空帧就退出 if (frame.empty()) break; namedWindow("本地摄像头",WINDOW_FREERATIO);//方便调节大小 imshow("本地摄像头",frame); //等待Esc按键,ESC键退出 int key = waitKey(20); if (key == 27) { cout << "按下Esc退出"<< endl; break; } } //4.realese()释放摄像头资源 cap.release(); destroyAllWindows(); return; }

3.创建主程序并编辑main.cpp

#include "QuickDemo.h" #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { QuickDemo qd; //案例①:读取摄像头,指定按键esc(ascii码值为27)退出浏览 qd.OpenCamera1(); }

3.案例②③ 读取摄像头/视频,截取保存图片

案例②③:读取摄像头,指定按键q(ascii码值为113)按序号保存图片,并指定按键esc(ascii码值为27)退出浏览

案例②③:读取摄像头,指定按键w(ascii码值为119)按时间保存图片,指定按键esc(ascii码值为27)退出浏览

在QuickDemo.h中添加

void SavePic(); void SavePicByOrder(Mat& iamge,int order); void SavePicByTime(Mat& iamge);

在QuickDemo.cpp中编写函数主体

/// <summary> /// 案例②③:读取摄像头,指定按键q(ascii码值为113)按序号保存图片,指定按键w(ascii码值为119)按时间保存图片,并指定按键esc(ascii码值为27)退出浏览 /// </summary> void QuickDemo::SavePic() { //1.创建视频捕获对象 VideoCapture cap; //打开默认摄像头,参数0代表本机摄像头 cap.open(0); //2.判断是否打开成功 isOpened() if (!cap.isOpened()) { cout << "摄像头打开失败!" << endl; return; } //3.创建图片数据对象 Mat frame; while (true) { //读取一帧画面 cap.read(frame); //读到空帧就退出 if (frame.empty()) break; namedWindow("本地摄像头", WINDOW_FREERATIO);//方便调节大小 imshow("本地摄像头",frame); //等待Esc按键,ESC键退出 int key = waitKey(20); switch (key) { case 113: //按键"q",按序号保存 { cout << "按键'q', 按序号保存" << endl; SavePicByOrder(frame,order++);break; } case 119: //按键"w",按时间保存 { cout << "按键'w', 按时间保存 " << endl; SavePicByTime(frame);break; } case 27: { cout << "按键Esc,退出" << endl; return; } } } //4.release()释放摄像头资源 cap.release(); destroyAllWindows(); } /// <summary> /// 按顺序保存图片 /// </summary> void QuickDemo::SavePicByOrder(Mat& image,int order) { cout << "按序号保存图片" << endl; string path = "D:\\img\\outImage\\num\\out"+to_string(order)+"Image.jpg"; imwrite(path, image); cout << "保存成功:" << path << endl; } /// <summary> /// 获取当前时间 /// </summary> /// <returns>时间字符串</returns> static string GetNowTime() { auto now = chrono::system_clock::now(); time_t t = chrono::system_clock::to_time_t(now); tm local_tm; localtime_s(&local_tm, &t);//安全版本 char buf[64]; strftime(buf, sizeof(buf), "%Y%m%d_%H%M%S", &local_tm); return string(buf); } /// <summary> /// 按时间保存图片 /// </summary> void QuickDemo::SavePicByTime(Mat&image) { cout << "按时间保存:" << endl; cout << "当前时间为:" << GetNowTime(); string path = "D:\\img\\outImage\\time\\out" + GetNowTime() + "Image.jpg"; imwrite(path, image); cout << "保存成功:" << path << endl; }

在主程序main.cpp中调用

#include "QuickDemo.h" #include <iostream> #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main() { QuickDemo qd; //案例②③:读取摄像头, // 指定按键q(ascii码值为113)按序号保存图片, // 指定按键w(ascii码值为119)按时间保存图片,并指定按键esc(ascii码值为27)退出浏览 qd.SavePic(); }

4.案例④⑤ 读取视频/摄像头,截取保存视频

案例④:读取摄像头,指定按键esc(ascii码值为27)退出浏览并保存视频

案例⑤:读取摄像头,指定按键a(ascii码值为97)开始录制视频,指定按键s(ascii码值为115)停止录制并保存视频,指定按键esc(ascii码值为27)退出浏览

在QuickDemo.h添加

void OpenAndSaveVideo();

在QuickDemo.cpp编写函数主体

/// <summary> ///案例④⑤:读取摄像头,指定按键a(ascii码值为97)开始录制视频,指定按键s(ascii码值为115)停止录制并保存视频,指定按键esc(ascii码值为27)退出浏览 /// </summary> void QuickDemo::OpenAndSaveVideo() { //创建视频流对象 VideoCapture vcp; vcp.open("D:\\img\\video\\test.avi"); if (!vcp.isOpened()) { cout << "视频打开失败!"; return; } cout << "视频打开成功" << endl; int vcFps = vcp.get(CAP_PROP_FPS);//获取帧率 int vcWidth = vcp.get(CAP_PROP_FRAME_WIDTH);//获取宽度 int vcHeight = vcp.get(CAP_PROP_FRAME_HEIGHT);//获取高度 //创建视频读取流对象 VideoWriter vw; bool IsStart = false;//是否开始录制 int frameCount = 0; string path; int order = 1; while (true) { Mat frame;//创建图片数据对象 vcp.read(frame);//从视频流读取图片 if (frame.empty()) { break; }//读取为空则结束 namedWindow("显示视频",WINDOW_FREERATIO);//方便调节大小 imshow("显示视频", frame); int key = waitKey(20); switch (key) { case 97: //按下'a'开始录制 { IsStart = true; cout << "开始录制:" << endl; path = "D:\\img\\outvideo\\out" + to_string(order++) + ".mp4"; vw.open(path, CAP_PROP_FOURCC, vcFps, Size(vcWidth, vcHeight)); break; } case 115: { IsStart = false; cout << "停止录制" << endl; cout << path << "保存成功"; vw.release(); break; } case 27: { cout << "退出程序" << endl; vw.release(); vcp.release(); destroyAllWindows(); return; } } if (IsStart) { frameCount++; cout << "当前帧数:"<<frameCount << endl; vw.write(frame); } } }

在主程序mainn.cpp中调用

qd.OpenAndSaveVideo();

5.案例⑥ 设置文件格式的三种方式

案例⑥:批量读取图片,有序的图片,多种字符串拼接的方法

在QuickDemo.h中添加方法

void ReadPicByOrder();

在QuickDemo.cpp中添加函数主体

/// <summary> /// 读取图片,文件名采用多种字符串拼接的方式 /// </summary> void QuickDemo::ReadPicByOrder() { //第一种字符串拼接方法,使用+ string str1 = "D:\\img\\image\\00"; string str2; string str3 = ".png"; string fileName, windowName; //第二种字符串拼接方法,使用字符数组 char fileNameArray[50]; char windowNameArray[20]; //第三种字符串拼接方式,使用format()进行格式化 string fName, wName; for (int index = 1;index < 9;index++) { fileName = str1 + to_string(index) + str3; //windowName = "图像显示" + to_string(index); //当窗口的名称随着index变化而变化的时候,会连续打开不同的窗口 windowName = "图像显示"; //当窗口的名称不发生改变的时候,图片会在同一个窗口内依次展示 Mat img = imread(fileName); namedWindow(windowName, WINDOW_FREERATIO); imshow(windowName, img); waitKey(1000); //每隔开1000ms,循环播放图片 } //第二种字符串拼接方法,使用字符数组格式化字符串 for (int index = 1;index < 9;index++) { sprintf_s(fileNameArray, "D:\\img\\image\\00%d.png", index); sprintf_s(windowNameArray, "图像显示%d", index); Mat img = imread(fileNameArray); namedWindow(windowNameArray, WINDOW_FREERATIO); imshow(windowNameArray, img); waitKey(1000); //每隔开1000ms,循环播放图片 } //第三种字符串拼接方法,使用format()格式化字符串 for (int index = 1;index < 9;index++) { fName = format("D:\\img\\image\\00%d.png", index); wName = format("图像显示%d", index); Mat img = imread(fName); namedWindow(wName, WINDOW_FREERATIO); imshow(wName, img); waitKey(1000); //每隔开1000ms,循环播放图片 } destroyAllWindows(); }

在主程序main.cpp中调用

qd.ReadPicByOrder();

6.案例⑦⑧视频的分解与合成

案例⑦:视频分解,读取视频并分解为一张一张的图片保存

案例⑧:图片合成视频:将一张一张的图片合成为视频保存

在头文件QuickDemo.h 中添加方法

void VideoToPics(); void PicsToVideo();

在QuickDemo.cpp中添加函数主体

/// <summary> /// 把视频分割为图片 /// </summary> void QuickDemo::VideoToPics() { VideoCapture vcp;//创建视频捕获对象 vcp.open("D:\\img\\video\\test.mp4");//读取本地文件 if (!vcp.isOpened()) { cout << "视频打开失败!"<<endl; return; } int frameCount = 0; while (true) { Mat frame;//创建图片数据对象 vcp.read(frame);//从视频流读取图片 if (frame.empty()) { return; };//读取为空则结束 cout << "当前帧数:" << frameCount << endl; imshow("显示视频",frame); imwrite("D:\\img\\outImage\\num\\"+to_string(frameCount++)+".jpg", frame); waitKey(20); frame.release();//释放图片对象 } vcp.release();//关闭视频流 } /// <summary> /// 把图片合成视频 /// </summary> void QuickDemo::PicsToVideo() { VideoWriter vw;//创建视频写入器 int fourcc = VideoWriter::fourcc('m', 'p', '4', 'v'); double fps = 25; Size imgSize(720, 1280);//图片实际宽×高 vw.open("D:\\img\\outvideo\\out.mp4",fourcc,fps,imgSize); if (!vw.isOpened()) { return; }//写入器打开失败,默认返回 string fileName; int frameCount = 0; while (true) { fileName = format("D:\\img\\outImage\\num\\%d.jpg",frameCount++); Mat frame = imread(fileName); cout << "正在读取:" << fileName << endl; if (frame.empty()) { break; }//读取为空,结束 imshow("显示视频",frame); vw.write(frame); waitKey(20); frame.release();//释放图片资源 } cout << "成功合成" << endl; vw.release();//释放写入器 destroyAllWindows(); }

在主程序main.cpp调用

//案例⑦:视频分解,读取视频并分解为一张一张的图片保存 //qd.VideoToPics(); //案例⑧:图片合成视频:将一张一张的图片合成为视频保存 qd.PicsToVideo();

所需素材下载(下载后,把原来文件名"0630img"改为"img",放在D盘下)

通过网盘分享的文件:0630img.zip 链接: 百度网盘 请输入提取码 提取码: nnrk

链接失效,请给我留言。如果不足,请业界大佬批评指正。

http://www.jsqmd.com/news/1099906/

相关文章:

  • 无人机合速度和航捷转速度分量
  • 大数据志愿填报冲稳保如何搭配院校梯度
  • 龙芯3B6000服务器手动安装Docker 29.5.1实战指南
  • PHP+VUE医疗预约系统毕业设计:全栈开发实战与部署指南
  • MultiFunPlayer完整指南:设备同步与媒体播放的终极解决方案
  • 新店起店怎么查抖音小店对标数据?蝉妈妈拆解头部4要点
  • Element Plus 级联选择器实战:仿学科网教材多级选择的完整方案
  • Java计算机毕设之基于 SpringBoot+Vue 的 4S 店客户跟进与购车管理系统的设计与实现 基于 SpringBoot+Vue 的汽车门店车辆(完整前后端代码+说明文档+LW,调试定制等)
  • 专访大晓机器人王飞:世界模型是“进化型基础设施”
  • 基于51/STM32单片机温度控制系统 恒温箱 水温控制 温度采集 成品1(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • HarmonyOS律愈实战02:ArkTS五音数据模型设计
  • esp32s3+ws2812灯条控制
  • 公开课紧张到忘词?老教师都在用的3个临场应对方法
  • LeetCode 热题 100 —— 7.接雨水(Javascript解法)
  • 别再盲目试用了!AI编程助手采购决策树:按团队规模、语言栈、安全等级自动匹配最优组合(含SaaS/私有化/混合部署ROI计算表)
  • 2026 年有哪些真正适合学生写开题的 AI 辅助写作工具,实测无套路分享
  • 【VMware磁盘扩容终极指南】:20年运维专家亲授5种零宕机扩容方案,99%的人不知道第3种!
  • Antigravity Manager:把多个 AI 账号管明白的桌面工具
  • Debian 12 编译安装网讯网卡驱动详细教程
  • Dism++深度解析:现代化Windows系统维护架构与技术实现
  • SCI投稿AI绘图避坑全攻略:AI打草稿+人工转矢量,彻底告别撤稿风险!
  • 从H100的异步执行和线程块集群,聊聊如何榨干GPU的每一分算力
  • 2026年技术方向怎么选?机器视觉、PLC、AI大模型、嵌入式深度对比
  • 宝塔面板部署 Spring Boot 项目全流程
  • Python爬虫经典案例018:爬虫性能优化与调优——从慢到快的全面优化指南
  • VisualCppRedist AIO:终极Windows运行库一体化智能管理解决方案深度解析
  • 【open harmony/harmonyos】HarmonyOS 应用中的数据模型分层:以星图节点 Store 为例
  • 2026年论文查重免费网站靠谱吗?这5个平台实测对比
  • 基于STM32单片机智能窗帘窗户光敏定时遥控温湿度语音物联网设计1(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 09502黄大年茶思屋榜文95期 第2题 高性能、适用于NPU硬件的Training-free大模型剪枝算法