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

Opencv4 c++ 自用笔记 03 滑动条、相机与视频操作

1. 相机与视频操作

1.1 打开视频/相机

OpenCV 中 imread() 只能读取静态图像,若要读取视频文件或摄像头流,需要使用 VideoCapture 类:

// 构造函数
cv::VideoCapture::VideoCapture();                      
cv::VideoCapture::VideoCapture(const std::string& filename, int apiPreference = cv::CAP_ANY);  // 打开视频文件,apiPreference为设置属性
cv::VideoCapture::VideoCapture(int index, int apiPreference = cv::CAP_ANY);                     // 打开摄像头,index 为设备 ID// 或者先默认构造,再调用 open()
VideoCapture cap;
cap.open("example.avi");
cap.open(0);

1.2 读取并播放视频

VideoCapture video("example.avi");
if (!video.isOpened()) {std::cerr << "Error: 无法打开视频文件!" << std::endl;return -1;
}double fps = video.get(cv::CAP_PROP_FPS);  // 读取帧率
int delay = static_cast<int>(1000.0 / fps); // 每帧显示时长(毫秒)while (true) {cv::Mat frame;video >> frame;                // 读取下一帧到 frameif (frame.empty()) break;      // 视频结束或读取失败则退出cv::imshow("Video Playback", frame);if (cv::waitKey(delay) == 'q') break;
}
video.release();
cv::destroyAllWindows();

2. 视频属性查询

使用 VideoCapture::get(propId) 可以获取视频或摄像头流的各种参数:

Property参数 ID
当前播放位置(毫秒)CAP_PROP_POS_MSEC (0)
视频宽度CAP_PROP_FRAME_WIDTH (3)
视频高度CAP_PROP_FRAME_HEIGHT (4)
帧率CAP_PROP_FPS (5)
编解码器CAP_PROP_FOURCC (6)
总帧数CAP_PROP_FRAME_COUNT (7)
返回图像格式CAP_PROP_FORMAT (8)
摄像头专属属性
亮度CAP_PROP_BRIGHTNESS (10)
对比度CAP_PROP_CONTRAST (11)
饱和度CAP_PROP_SATURATION (12)
色调CAP_PROP_HUE (13)
增益CAP_PROP_GAIN (14)

示例:

double width  = video.get(cv::CAP_PROP_FRAME_WIDTH);
double height = video.get(cv::CAP_PROP_FRAME_HEIGHT);

3. 视频写入与保存

3.1 VideoWriter

// 构造函数
cv::VideoWriter::VideoWriter();
cv::VideoWriter::VideoWriter(const std::string& filename,int fourcc, double fps, cv::Size frameSize, bool isColor = true);

filename:输出文件路径及名称(带后缀)
fourcc:编码格式,使用 VideoWriter::fourcc('M','J','P','G') 等,-1为自动采用合适的编解码器
fps:输出帧率
frameSize:视频分辨率(宽, 高)
isColor:是否彩色(true/false

3.2 保存摄像头视频

#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main() {VideoCapture cap(0);if (!cap.isOpened()) {cerr << "Error: 无法打开摄像头!" << endl;return -1;}// 读取第一帧以获取格式Mat frame;cap.read(frame);bool isColor = (frame.type() == CV_8UC3);// 配置 VideoWriterint codec = VideoWriter::fourcc('M','J','P','G');double fps = 30.0;Size size(640, 480);VideoWriter writer("output.avi", codec, fps, size, isColor);if (!writer.isOpened()) {cerr << "Error: 无法创建视频写入器!" << endl;return -1;}// 循环读取并写入while (1) {if (!cap.read(frame) || frame.empty()) {cerr << "Error: 无法读取帧或帧为空!" << endl;break;}writer.write(frame);imshow("Capture & Save", frame);if (waitKey(30) == 'q') {cout << "退出程序" << endl;break;}}cap.release();writer.release();destroyAllWindows();return 0;
}

4. 窗口交互与滑动条

4.1 创建滑动条

createTrackbar(trackbarName, windowName, &value, maxCount, callback, userdata=0);

trackbarName:滑动条名称
windowName:所属窗口名称
value:滑动条的当前值(整型指针)
maxCount:滑动条最大值
callback:回调函数,每次滑动时调用
userdata:用户自定义数据指针(可选)

4.2 示例:图像阈值调整

#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int maxValue = 127;
Mat gray, binary;void callback(int, void*) {adaptiveThreshold(gray, binary, maxValue,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY, 11, 2);imshow("Thresh", binary);
}int main() {string inputPath  = "/home/user/test.jpg";string outputPath = "/home/user/outputs.jpg";gray = imread(inputPath, IMREAD_GRAYSCALE);if (gray.empty()) {cerr << "Error: 无法读取输入图像!" << endl;return -1;}namedWindow("Thresh");createTrackbar("MaxValue", "Thresh", &maxValue, 255, onTrackbar);// 初始显示onTrackbar(0, nullptr);while (true) {char key = (char)waitKey(10);if (key == 'q') {imwrite(outputPath, binary);cout << "结果已保存到: " << outputPath << endl;break;}}destroyAllWindows();return 0;
}

回调函数签名void callback(int pos, void* userdata);
每次滑动时,pos 为当前滑动位置,可用全局变量或 getTrackbarPos() 获取最新值。

5. 相机图像处理示例

上述代码中实现了利用滑动条调整二值化图像中的阈值,核心在于callback函数对图像的更新。

#include <opencv2/opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int maxValue = 127;
Mat gray, binary;void callback(int, void*) {adaptiveThreshold(gray, binary, maxValue,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY, 11, 2);imshow("Binary", binary);
}int main() {VideoCapture cap(0);if (!cap.isOpened()) {cerr << "Error: 无法打开摄像头!" << endl;return -1;}namedWindow("Binary");createTrackbar("Threshold", "Binary", &maxValue, 255, onTrackbar);while (1) {Mat frame;cap >> frame;if (frame.empty()) {cerr << "Error: 捕获帧为空!" << endl;break;}// 转灰度并二值化cvtColor(frame, gray, COLOR_BGR2GRAY);onTrackbar(0, nullptr);  // 初始更新一次imshow("Binary", binary);if (waitKey(30) == 'q') {destroyWindow("Binary");break;}}cap.release();return 0;
}

相关文章:

  • Spring Boot深度解析:自动配置、Starter依赖与MyBatis Plus集成指南
  • 【iptables防火墙】-- URL过滤 (Hexstring、IP、DoT和DoH)
  • Spring Boot微服务架构(九):设计哲学是什么?
  • VScode ios 模拟器安装cocoapods
  • 广州邮科高频开关电源:以创新科技赋能通信能源绿色未来
  • 代码随想录打卡|Day53 图论(Floyd 算法精讲 、A * 算法精讲 (A star算法)、最短路算法总结篇、图论总结 )
  • 电子书阅读器:基于UDP的网络日志调试系统
  • python打卡day40
  • TF 卡 U1 与 U3 的核心差异解析:从速度标准到应用场景
  • dvwa3——CSRF
  • 智能改变一切:当技术革命遇见人类文明
  • MySql(八)
  • Java本地缓存实现方案全解析:原理、优缺点与应用场景
  • 第十二篇:MySQL 分布式架构演进与云原生数据库探索
  • 针对Helsinki-NLP/opus-mt-zh-en模型进行双向互翻的微调
  • 大厂前端研发岗位设计的30道Webpack面试题及解析
  • ROS 2 中的 robot_state_publisher 和 joint_state_publisher 详解
  • comfyui 工作流中 视频长度和哪些参数有关? 生成15秒的视频,再加上RTX4060 8G显卡,尝试一下
  • AI书签管理工具开发全记录(五):后端服务搭建与API实现
  • (18)混合云架构部署
  • 推广网站都有哪些/十大经典广告营销案例
  • 磁县网站推广/广告联盟app
  • 网站开发工具/超级外链工具有用吗
  • dede网站根目录/武汉seo管理
  • 电子书网站开发/免费网站推广方式
  • 西宁建站/简单的个人网页制作html