当前位置: 首页 > 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.gsyq.cn/news/1611871.html

相关文章:

  • 新店起店怎么查抖音小店对标数据?蝉妈妈拆解头部4要点
  • 专访大晓机器人王飞:世界模型是“进化型基础设施”
  • 基于51/STM32单片机温度控制系统 恒温箱 水温控制 温度采集 成品1(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 别再盲目试用了!AI编程助手采购决策树:按团队规模、语言栈、安全等级自动匹配最优组合(含SaaS/私有化/混合部署ROI计算表)
  • 公开课紧张到忘词?老教师都在用的3个临场应对方法
  • Dism++深度解析:现代化Windows系统维护架构与技术实现
  • 【VMware磁盘扩容终极指南】:20年运维专家亲授5种零宕机扩容方案,99%的人不知道第3种!
  • 2026年技术方向怎么选?机器视觉、PLC、AI大模型、嵌入式深度对比
  • 从H100的异步执行和线程块集群,聊聊如何榨干GPU的每一分算力
  • Python爬虫经典案例018:爬虫性能优化与调优——从慢到快的全面优化指南
  • VisualCppRedist AIO:终极Windows运行库一体化智能管理解决方案深度解析
  • 国家标准起草单位是什么?有什么价值?企业如何申请参与国标制定
  • 上门按摩APP小程序开发公司,获客新思路:酒店渠道为什么值得做
  • 如何在一部手机上实现工作与生活数据的完全隔离?
  • SIM 卡克隆工具指南:安全移动 SIM 卡数据
  • 如何利用多人协作在线表格提升团队效率?告别协作混乱与数据勒索
  • API受限下15种LLM幻觉抑制创新方法
  • Unreal Engine 5.7 C++ 完整说明(C++ 标准、内置库、第三方库、内存 GC)
  • 课堂时间总不够用?这5个环节压缩技巧让教学节奏更从容
  • Claude Opus 4.8快速模式集成GitHub Copilot:AI编码响应速度实测与提效指南
  • 汇编指令补充
  • 湘美谈教育湘美书院成功学系列:AI时代的,图书的意义
  • 哈夫曼树的构造、编码生成与带权路径长度计算——基于C语言的实验实现与分析 P12114068王勇豪
  • 基于STM32单片机智能手环心率血氧体温GPS定位跌倒计步器系统设计1(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • P1375 小猫【洛谷算法习题】
  • 村花云 - 高性价比云服务器服务平台
  • 汇编——比较指令和条件跳转指令
  • web安全代码基础-PHP(模板组件插件安全)
  • FastAPI 基础篇:类型注解驱动的 Python Web 开发范式
  • ros2 humble安装anaconda