OpenCV 视频处理与摄像头操作详解

1. 引言

大家都来写OpenCV😊,学的好开心!


2. 视频基础与OpenCV简介

2.1 视频的定义

视频(Video)是由一系列静态图像(帧)以一定速率连续播放形成的动态影像。其本质是利用人眼的视觉暂留效应,将静止的画面转化为连续的动态内容。视频通常包含画面、音频轨道,有时还包括字幕、特效等信息。

视频的主要应用领域
  • 影视娱乐
  • 教育培训
  • 安防监控
  • 通信与直播
  • 自动驾驶与智能交通

2.2 OpenCV简介

OpenCV(Open Source Computer Vision Library)是一个跨平台的计算机视觉和机器学习软件库,支持C++、Python等多种语言。它为视频处理、图像分析、机器学习等任务提供了高效的算法和接口。


3. 视频读写

3.1 视频的基本操作

图片转视频

将多张图片按顺序和时间间隔组合,添加转场、音乐、字幕等,生成视频。例如旅游纪念视频、照片合成动画等。

视频转图片

从视频中提取特定帧作为图片,用于精彩瞬间捕捉、视频封面、画面分析等。例如电影剧照、运动分析等。

3.2 OpenCV读取视频详解

OpenCV通过cv::VideoCapture类实现视频文件或摄像头流的读取。

代码示例
#include <opencv2/opencv.hpp>#include <iostream>using namespace cv;using namespace std;int main(){//1 指定视频文件路径创建VideoCapture VideoCapture cap("C:/Users/Administrator/Desktop/video/cat.mp4");//2 判断是否成功打开视频if (!cap.isOpened()){cout << "视频打开失败!" << endl;return -1;}//3 获取视频基本信息double width = cap.get(CAP_PROP_FRAME_WIDTH);double height = cap.get(CAP_PROP_FRAME_HEIGHT);double count = cap.get(CAP_PROP_FRAME_COUNT);double fps = cap.get(CAP_PROP_FPS);cout << "视频的宽=" << width << endl;cout << "视频的高=" << height << endl;cout << "视频的总帧数=" << count << endl;cout << "视频的fps=" << fps << endl;//4 逐帧读取视频并展示Mat frame;width = width * 0.2;height = height * 0.2;while (true){cap >> frame;if (frame.empty()){break;}Mat dst;resize(frame, dst, Size(width,height));Mat gray;cvtColor(dst, gray, COLOR_BGR2GRAY);imshow("video", dst);imshow("gray video", gray);if (waitKey(1000/fps) == 27){break;}}//5 释放资源cap.release();destroyAllWindows();return 0;}
视频属性表
属性名说明类型示例值
CAP_PROP_FRAME_WIDTH视频帧宽度(像素)double1920
CAP_PROP_FRAME_HEIGHT视频帧高度(像素)double1080
CAP_PROP_FPS视频帧率(帧/秒)double30.0
CAP_PROP_FRAME_COUNT视频总帧数double2500
CAP_PROP_POS_FRAMES当前帧索引(从0开始)double100
CAP_PROP_POS_MSEC当前时间戳(毫秒)double3500.0
CAP_PROP_FOURCC编解码器FourCC代码double1196444237
CAP_PROP_BRIGHTNESS摄像头亮度(仅摄像头有效)double0.5
CAP_PROP_CONTRAST摄像头对比度double0.3
CAP_PROP_SATURATION摄像头饱和度double0.8
CAP_PROP_EXPOSURE摄像头曝光值double-4.0
CAP_PROP_AUTOFOCUS自动对焦是否开启double1.0

3.3 视频保存与编码格式

OpenCV通过cv::VideoWriter类实现视频录制与保存。

FourCC编码格式
  • 'MJPG':Motion-JPEG,常用于.avi文件
  • 'XVID':XVID编码,适用于.avi文件
  • 'H264':H.264编码,适用于.mp4文件(需安装OpenH264库)
视频保存代码示例
void writeVideo(VideoCapture& cap){cv::String fileName = "C:/Users/Administrator/Desktop/video/temp.avi";int fourcc = VideoWriter::fourcc('M', 'J', 'P', 'G');double width = cap.get(CAP_PROP_FRAME_WIDTH);double height = cap.get(CAP_PROP_FRAME_HEIGHT);double fps = cap.get(CAP_PROP_FPS);VideoWriter writer(fileName,fourcc,fps,Size(width,height),false);if (!writer.isOpened()){cout << "视频文件打开失败!" << endl;return;}Mat src;while (true){cap >> src;if (src.empty()){break;}Mat gray;cvtColor(src, gray, COLOR_BGR2GRAY);writer.write(gray);if (waitKey(30) == 27){break;}}cout << "已经成功保存视频" << endl;writer.release();}
视频保存流程
  1. 创建VideoWriter对象,指定文件名、编码格式、帧率、分辨率、是否彩色
  2. 判断文件是否成功打开
  3. 逐帧写入视频
  4. 释放资源

4. 视频追踪

4.1 视频追踪定义与应用

视频追踪(Video Tracking)是指在连续的视频帧中定位并跟踪特定目标(如人脸、车辆)的运动轨迹。广泛应用于:

  • 安防监控
  • 自动驾驶
  • 人机交互
  • 运动分析
视频追踪流程
  1. 目标检测:识别并定位目标
  2. 特征提取:提取目标特征(颜色、形状、纹理等)
  3. 模型更新:适应目标外观变化
  4. 位置预测与校正:预测目标位置并校正

4.2 Meanshift算法原理与实现

Meanshift算法定义

Meanshift是一种基于密度估计的非参数化聚类算法,广泛用于目标追踪。其核心思想是通过迭代将搜索窗口向目标区域的颜色直方图分布中心移动,实现目标定位。

直方图反向投影

直方图反向投影是指将目标区域的颜色分布映射到整幅图像,得到每个像素属于目标的概率图。

反向投影流程
  1. 选定目标区域,计算HSV直方图
  2. 对每一帧计算直方图
  3. 对比直方图,得到相似度
  4. 生成概率图,作为Meanshift输入
Meanshift代码解析
void meanshiftTest(VideoCapture& cap){Mat frame;cap >> frame;if (frame.empty()){cout << "无法读取视频帧" << endl;return;}Rect roi = selectROI("请选择追踪目标",frame,false);if (roi.width <= 0 || roi.height <= 0){cout << "已取消选择roi区域" << endl;return;}Mat target = frame(roi).clone();imshow("target", target);Mat hsv_target;cvtColor(target, hsv_target, COLOR_BGR2HSV);Mat mask;inRange(hsv_target, Scalar(0, 30, 0), Scalar(180, 255, 255), mask);int histSize = 180;float range[] = { 0,180 };const float* histRange = { range };Mat hist_target;int channels[] = { 0 };calcHist(&hsv_target, 1, channels, mask, hist_target, 1, &histSize, &histRange);normalize(hist_target, hist_target, 0,255, NORM_MINMAX);TermCriteria criteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1);while (true){cap >> frame;if (frame.empty()){break;}Mat hsvFrame;cvtColor(frame, hsvFrame, COLOR_BGR2HSV);Mat back;calcBackProject(&hsvFrame, 1, channels, hist_target, back,&histRange);meanShift(back, roi, criteria);rectangle(frame, roi, Scalar(0, 255, 0));imshow("视频追踪", frame);if (waitKey(30) == 27){break;}}}
关键函数说明
  • selectROI:手动选择目标区域
  • calcHist:计算目标区域颜色直方图
  • normalize:归一化直方图
  • calcBackProject:计算反向投影概率图
  • meanShift:执行Meanshift迭代,更新目标位置
TermCriteria参数说明
参数类型说明
TermCriteria::EPS收敛到指定精度时终止
TermCriteria::COUNT达到最大迭代次数时终止
10最大迭代次数
1精度阈值(像素)

4.3 Camshift算法原理与实现

Camshift算法定义

Camshift(Continuously Adaptive Mean Shift)是Meanshift的改进版,能自适应调整搜索窗口的大小和方向,适合目标尺度和方向变化明显的场景。

Camshift实现流程
  1. 初始化目标模型,计算颜色直方图
  2. 定义搜索窗口
  3. 执行Meanshift迭代
  4. 根据目标分布调整窗口大小和方向
  5. 更新窗口位置,输出最佳拟合椭圆
Camshift代码解析
void camshiftTest(VideoCapture& cap){Mat frame;cap >> frame;if (frame.empty()){cout << "无法读取视频帧" << endl;return;}Rect roi = selectROI("请选择追踪目标", frame, false);if (roi.width <= 0 || roi.height <= 0){cout << "已取消选择roi区域" << endl;return;}Mat target = frame(roi).clone();imshow("target", target);Mat hsv_target;cvtColor(target, hsv_target, COLOR_BGR2HSV);Mat mask;inRange(hsv_target, Scalar(0, 60, 32), Scalar(180, 255, 255), mask);int histSize = 180;float range[] = { 0,180 };const float* histRange = { range };Mat hist_target;int channels[] = { 0 };calcHist(&hsv_target, 1, channels, mask, hist_target, 1, &histSize, &histRange);normalize(hist_target, hist_target, 0, 255, NORM_MINMAX);TermCriteria criteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1);while (true){cap >> frame;if (frame.empty()){break;}Mat hsvFrame;cvtColor(frame, hsvFrame, COLOR_BGR2HSV);Mat back;calcBackProject(&hsvFrame, 1, channels, hist_target, back, &histRange);RotatedRect trackBox = CamShift(back, roi, criteria);rectangle(frame, roi, Scalar(0, 255, 0));//ellipse(frame, trackBox, Scalar(0, 0, 255), 2);imshow("视频追踪", frame);if (waitKey(30) == 27){break;}}}
Camshift返回值说明
  • RotatedRect:最佳拟合椭圆,包含中心位置、大小、旋转角度

4.4 Meanshift与Camshift对比分析

算法窗口大小适应目标变化适用场景实时性输出信息
Meanshift固定不适应目标大小不变极高位置
Camshift自适应适应目标尺度/方向变化较高位置+大小+方向
选择建议
  • 优先Meanshift:目标大小和方向基本不变,对实时性要求极高
  • 优先Camshift:目标尺度或方向变化明显,需要输出目标朝向信息

5. 摄像头实时处理

5.1 实时处理定义与应用

摄像头实时处理是指通过摄像头捕获视频流,对每一帧图像进行即时处理和分析,并实时显示或反馈结果。应用包括:

  • 实时人脸检测
  • 运动物体追踪
  • 增强现实(AR)效果

5.2 摄像头实时捕获与处理流程

  1. 打开摄像头(cv::VideoCapture
  2. 逐帧读取视频流
  3. 对每一帧进行处理(如灰度化、边缘检测等)
  4. 实时显示处理结果(cv::imshow
  5. 释放资源
摄像头实时处理代码解析
void cameraTest(){VideoCapture cap(0);cap.set(CAP_PROP_FRAME_WIDTH,680);cap.set(CAP_PROP_FRAME_HEIGHT, 480);Mat frame;while (true){cap >> frame;if (frame.empty()){cout << "无法读取摄像头帧" << endl;break;}Mat gray;cvtColor(frame, gray, COLOR_BGR2GRAY);imshow("实时帧", frame);imshow("灰度帧", gray);if (waitKey(30) == 27){break;}}cap.release();destroyAllWindows();}

5.3 实时视频处理应用举例

5.3.1 实时跟踪

利用Meanshift或Camshift算法对摄像头捕获内容进行实时目标跟踪。

void camShiftCameraTest(){VideoCapture cap(0);Mat frame;cap >> frame;if (frame.empty()){cout << "无法读取视频帧" << endl;return;}Rect roi = selectROI("请选择追踪目标", frame, false);if (roi.width <= 0 || roi.height <= 0){cout << "已取消选择roi区域" << endl;return;}Mat target = frame(roi).clone();imshow("target", target);Mat hsv_target;cvtColor(target, hsv_target, COLOR_BGR2HSV);Mat mask;inRange(hsv_target, Scalar(0, 60, 32), Scalar(180, 255, 255), mask);int histSize = 180;float range[] = { 0,180 };const float* histRange = { range };Mat hist_target;int channels[] = { 0 };calcHist(&hsv_target, 1, channels, mask, hist_target, 1, &histSize, &histRange);normalize(hist_target, hist_target, 0, 255, NORM_MINMAX);TermCriteria criteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1);while (true){cap >> frame;if (frame.empty()){break;}Mat hsvFrame;cvtColor(frame, hsvFrame, COLOR_BGR2HSV);Mat back;calcBackProject(&hsvFrame, 1, channels, hist_target, back, &histRange);RotatedRect trackBox = CamShift(back, roi, criteria);rectangle(frame, roi, Scalar(0, 255, 0));//ellipse(frame, trackBox, Scalar(0, 0, 255), 2);imshow("视频追踪", frame);if (waitKey(30) == 27){break;}}destroyAllWindows();}
5.3.2 实时边缘检测

通过摄像头实时捕获视频,使用Canny算法提取图像边缘。
​​​​​

void cameraCannyTest(){VideoCapture cap(0);cap.set(CAP_PROP_FRAME_WIDTH, 680);cap.set(CAP_PROP_FRAME_HEIGHT, 480);Mat frame;while (true){cap >> frame;if (frame.empty()){cout << "无法读取摄像头帧" << endl;break;}Mat gray;cvtColor(frame, gray, COLOR_BGR2GRAY);Mat blur;GaussianBlur(gray, blur, Size(3, 3),1.5);Mat dst;Canny(blur, dst, 50, 150);imshow("实时帧", frame);imshow("边缘检测", dst);if (waitKey(30) == 27){break;}}cap.release();destroyAllWindows();}
5.3.3 其他应用

摄像头实时捕获内容不仅能做跟踪和边缘检测,还可用于:

  • 实时人脸识别
  • 实时手势识别
  • 实时目标分割
  • 实时AR效果叠加

6. 总结与展望

好学,爱学,还得学!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/88966.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/88966.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Agentic AI 的威胁与缓解措施

原文&#xff1a;https://www.aigl.blog/content/files/2025/04/Agentic-AI—Threats-and-Mitigations.pdf AI Agent 的定义 1. 定义与基础 智能代理&#xff08;Agent&#xff09;的定义&#xff1a; 智能代理是一种能够感知环境、进行推理、做出决策并自主采取行动以实现特定…

ArrayList列表解析

ArrayList集合 ArrayList 的底层是数组队列&#xff0c;相当于动态数组。与 Java 中的数组相比&#xff0c;它的容量能动态增长。在添加大量元素前&#xff0c;应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。 ArrayList 继承…

《恋与深空》中龙和蛇分别是谁的代表

在《恋与深空》宏大而神秘的世界观中&#xff0c;每一个符号都蕴含着深意。当玩家们热议“龙”和“蛇”这两种强大而古老的生物究竟代表着谁时&#xff0c;所有的线索都默契地指向了同一个名字——秦彻。 他不仅是力量与权威的象征“恶龙”&#xff0c;也是背负着宿命与纠葛的“…

gitignore添加后如何生效?

清除 Git 缓存&#xff1a; git rm -r --cached .添加文件到 Git&#xff1a;git add .使用 git commit 命令提交这些更改git commit -m "Update .gitignore"

多尺度频率辅助类 Mamba 线性注意力模块(MFM),融合频域和空域特征,提升多尺度、复杂场景下的目标检测能力

在伪装物体检测领域&#xff0c;现有方法大多依赖空间局部特征&#xff0c;难以有效捕捉全局信息&#xff0c;而 Transformer 类方法虽能建模长距离依赖关系&#xff0c;却存在计算成本高、网络结构复杂的问题。同时&#xff0c;频域特征虽具备全局建模能力&#xff0c;可频繁的…

Dify的默认端口怎么修改

1.定位配置文件 在 Dify 的安装目录中找到 .env 文件&#xff08;通常位于 docker/ 子目录下&#xff09;。此文件定义了 Docker 容器的环境变量&#xff0c;包括端口配置。 2.调整端口参数 修改以下两个关键配置项&#xff1a; # Docker 容器内部 Nginx 监听的端口&#xf…

Go内存分配

图解Go语言内存分配 - 知乎 go内置运行时&#xff0c;采用了自主管理&#xff0c;实现更好的内存使用模式&#xff0c;不需要每次内存分配都进行系统调用 采用TCMalloc算法&#xff1a;把内存分为多级管理&#xff0c;从而降低锁的粒度 将可用的堆内存采用二级分配的方式进行…

cursor使用mcp连接mysql数据库,url方式

背景。 用cursor生成后端代码。让cursor可以创建响应的表结构以及插入数据。使用的cursor版本是1.2.1 cursor 官网 mcp 说明smithery 中mysql mcp这个mcp具有建表的本领。 在cursor中是这样配置的。 以上这种配置方式是是通过在smithery 网站中配置好自己的mysql数据库连接后才…

Twisted study notes[1]

文章目录serverreferencesserver Twisted usually using subclass twisted.internet.protocol.Protocol to treat protocols .Protocol is a fundamental class in Twisted for implementing network protocols.protocol class instant don’t exists forever because of it w…

Python 数据建模与分析项目实战预备 Day 6 - 多模型对比与交叉验证验证策略

✅ 今日目标 引入多种常见分类模型&#xff08;随机森林、支持向量机、K近邻等&#xff09;比较不同模型的训练效果使用交叉验证提升评估稳定性&#x1f9fe; 一、对比模型列表模型类名&#xff08;sklearn&#xff09;适用说明逻辑回归LogisticRegression基础线、易于解释KNNK…

xss-labs 1-8关

level1打开检查&#xff0c;发现test直接放入h2标签中此时通过script绕过h2标签构造payload127.0.0.1/xss-labs/lvel1.php?name<script>alert(111)</script>直接使用script标签绕过h2,并执行alert,通过level2打开检查&#xff0c;输入的123被放在input标签里面的v…

Conda 核心命令快速查阅表

本表旨在提供一个简洁、高效的 Conda 命令参考&#xff0c;专注于最常用功能的快速查找。 1. 环境管理 (Environment Management)功能 (Function)命令 (Command)示例 (Example)创建新环境conda create -n <env_name> [packages...]conda create -n myenv python3.9 panda…

音视频学习(三十九):IDR帧和I帧

主要区分&#xff1a;I 帧 是帧内编码帧&#xff0c;IDR 帧 是一种特殊的 I 帧&#xff0c;它是“清除参考帧链的强制切断点”。H.264 视频结构 结构 H.264 视频由多个 NAL&#xff08;Network Abstraction Layer&#xff09;单元 构成&#xff0c;每一帧图像可由一个或多个 NA…

人工智能与机器学习暑期科研项目招募(可发表论文)

人工智能与机器学习暑期科研项目招募 华中科技大学博士论文指导我是计算机专业的研二学生&#xff1a;从大二开始接触科研&#xff0c;至今已发表1篇CCF-A类会议论文、1篇CCF-B类会议论文&#xff0c;以及2篇Top期刊论文。正是这段从本科开始的科研经历&#xff0c;让我在保研和…

C盘爆满?一键清理恢复极速体验!“小番茄C盘清理”彻底解放你的电脑

目录 前言 C盘变红&#xff1f;&#xff01;那么你的电脑将会出现下面糟糕的情况&#xff1a; 一、小番茄C盘清理介绍——拯救你的C盘爆红&#xff01; 二、安装登录小番茄C盘清理 2.1 安装小番茄C盘清理 2.2 登录—拥有专属自己电脑的小番茄C盘清理 三、手把手教你深度…

UI前端大数据可视化实战技巧:如何利用数据故事化提升用户参与度?

hello宝子们...我们是艾斯视觉擅长ui设计、前端开发、数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩!一、引言&#xff1a;从 “图表堆砌” 到 “故事共鸣” 的可视化革命当企业管理者面对布满折线…

CSS基础1.1

HTML骨架<!DOCTYPE html> <!-- 中文网站 --> <html lang"zh-CN"> <head><!--charset"UTF-8" 规定网页的字符编码 --><meta charset"UTF-8"><!-- ie(兼容性差) / edge --><meta http-equiv"X…

前端基础JavaScript 笔记

本文是基于 B 站 pink 老师前端 JavaScript 课程整理的学习笔记 JS简介 JavaScript是一种运行在客户端&#xff08;浏览器&#xff09;的编程语言 作用&#xff1a;1.网页特效(监听用户的一些行为让网页作出对应的反馈) 2.表单验证(针对表单数据的合法性进行判断) 3.数据交互…

「小程序开发」项目结构和页面组成

微信小程序目录 微信小程序的目录,每种文件都有特定用途,组合起来才能构建完整应用。 小程序最基本的目录结构通常包含这些部分: my-miniprogram/ ├── pages/ // 存放所有页面 │ ├── index/ // 存放index页面的逻辑文件 │ └── logs/ …

[element-ui]el-table在可视区域底部固定一个横向滚动条

背景当el-table的列太多时&#xff0c;得拖动横向滚动条才能看到&#xff0c;但如果内容也很多&#xff0c;可能横向滚动条还看不到&#xff0c;又得滑到最下方才能拖动滚动条&#xff0c;这样不太方便。若内容过多时&#xff0c;有个固定在可视区域的横向滚动条就好了&#xf…