尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

OpenCV 滑动条

OpenCV 滑动条
📅 发布时间:2026/7/13 16:18:13

案例一、通过滑动条修改高、低阈值控制边缘检测

在QuickDemo.h中添加

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

在主程序main.cpp中调用

#include "QuickDemo.h" #include <iostream> using namespace cv; using namespace std; int main() { QuickDemo qd; qd.track_bar(); }

在QuickDemo.cpp中编辑函数主体

Mat src, dst; int minValue = 100;//Canny算法的第三个参数:低阈值 int maxValue = 200;//Canny算法的第四个参数:高阈值 void onChange(int,void*)//2. { Canny(src,dst,minValue,maxValue); imshow("滑动条操作窗口",dst); } /// <summary> /// 滑动条控制 /// </summary> void QuickDemo::track_bar() { //1.加载图片图像数据 src = imread("D:\\img\\image\\004.png"); if (src.empty()) { cout << "图片加载失败";return; } imshow("src",src); /*Mat dst; Canny(src,dst,100,200); imshow("dst",dst);*/ namedWindow("滑动条操作窗口",1); //第一步:创建滑动条,指定依附的窗口,并设置指定的滑动条回调函数 createTrackbar("低阈值","滑动条操作窗口",&minValue,255, onChange,0); createTrackbar("高阈值", "滑动条操作窗口", &maxValue, 255, onChange, 0); while (true) { //imshow("滑动条操作窗口", src); int key = waitKey(20); if (key == 27) break; } src.release(); destroyAllWindows(); }

案例二、OpenCV视频+滑动条控制思路

难点1:如何获取总时长、当前时长

解决: 获取视频的帧率,总帧数 视频总时长=总帧数/帧率

int fps = vcp.get(CAP_PROP_FPS);//获取帧率 int frame_count = vcp.get(CAP_PROP_FRAME_COUNT);//总帧数 int second_total = frame_count / fps;//总时长

当前时长=当前帧数/帧率

double frame_current = vcp.get(CAP_PROP_POS_FRAMES);//当前帧数 int second_current = frame_current / fps;//当前时长

难点2:多次回调,程序崩溃

解决:设置手动拖动锁,自动刷新锁

bool isDragging = false;//用户手动拖动滑块锁
bool autoSyncLock = false; // 代码自动刷新滑块锁

在视频播放while循环中编辑

if (!isDragging) { autoSyncLock = true; //上锁:告知回调这是代码自动刷新 setTrackbarPos("播放进度", "显示视频", (int)frame_current); autoSyncLock = false; //解锁 }

在滑动条回调函数中编辑

void on_trackbar_video(int, void*) { if (autoSyncLock) return; //代码自动更新滑块时,直接跳过回调,阻断递归 isDragging = true;//标记正在拖拽,暂停自动刷新 play_video(vcp,frame_current); }

难点3:播放、暂停

int isPlay = 1; // 1播放 0暂停,存储滑动条的值 bool isPlayFlag = true; //是否播放

在滑动条回调函数中编辑

void on_stop_video(int, void*) { isPlayFlag = (isPlay == 1) ? true : false; }

在视频播放while循环中添加

while(true) { if(isPlayFlag) { } }

上面是核心代码,下面是全部代码

在QuickDemo.h中添加

void trackbar_video();

在主程序main.cpp中调用

QuickDemo qd; qd.trackbar_video();

在QuickDemo.cpp中编辑函数主体

/// <summary> /// 返回总时长 /// </summary> /// <param name="seconds"></param> /// <returns></returns> string getDuration(int second_total) { //不超过1小时 int minute = second_total / 60; int second = second_total % 60; string min_str = (minute >= 10) ? to_string(minute) : "0" + to_string(minute); string sec_str = (second >= 10) ? to_string(second) : "0" + to_string(second); return min_str + ':' + sec_str; } /// <summary> /// 根据当前帧数,返回当前播放进度 /// </summary> /// <param name="frame_current"></param> /// <returns></returns> string getCurrentProgress(int frame_current,int fps) { int second_current = frame_current / fps; int minute = second_current / 60; int second = second_current % 60; string min_str = (minute>=10) ? to_string(minute) : "0" + to_string(minute); string sec_str = (second>=10)? to_string(second) : "0" + to_string(second); return min_str + ':' + sec_str; } int frame_current; VideoCapture vcp; bool isDragging = false;//用户手动拖动滑块锁 bool autoSyncLock = false; // 代码自动刷新滑块锁 int isPlay = 1; // 1播放 0暂停,存储滑动条的值 bool isPlayFlag = true; //是否播放 /// <summary> /// 正常从0帧播放视频 /// </summary> /// <param name="vcp"></param> void play_video(VideoCapture vcp) { int fps = vcp.get(CAP_PROP_FPS);//获取帧率 int frame_count = vcp.get(CAP_PROP_FRAME_COUNT);//总帧数 int second_total = frame_count / fps;//总时长 //cout << "帧率:" << fps << "总帧数:" << frame_count << "总时长:" << second_total << endl; while (true) { if(isPlayFlag) { Mat frame;//创建图片数据对象 vcp.read(frame); if (frame.empty()) { break; }//读取为空则结束 //获取当前帧数 double frame_current = vcp.get(CAP_PROP_POS_FRAMES); cout << "当前帧数:"<<frame_current << endl; if (!isDragging) { autoSyncLock = true; //上锁:告知回调这是代码自动刷新 setTrackbarPos("播放进度", "显示视频", (int)frame_current); autoSyncLock = false; //解锁 } string result = getCurrentProgress((int)frame_current, fps) + "/" + getDuration(second_total); result += " fps:" + to_string(fps)+"fps_current:"+ to_string(frame_current); putText(frame, result,Point(30,30),1,2,Scalar(0,0,255),2,8); imshow("显示视频", frame); } int key = waitKey(20); if (key == 27) break; isDragging = false; } vcp.release(); destroyAllWindows(); } /// <summary> /// 从当前帧播放视频 /// </summary> /// <param name="vcp">视频数据</param> /// <param name="frame_current">当前帧</param> void play_video(VideoCapture vcp, double frame_current) { int fps = vcp.get(CAP_PROP_FPS);//获取帧率 int frame_count = vcp.get(CAP_PROP_FRAME_COUNT);//总帧数 int second_total = frame_count / fps;//总时长 cout << "帧率:" << fps << "总帧数:" << frame_count << "总时长:" << second_total << endl; vcp.set(CAP_PROP_POS_FRAMES, frame_current); //校验是否跳转成功(很多时候不会精准跳转到100,会跳到 最近1帧) frame_current = vcp.get(CAP_PROP_POS_FRAMES); cout << "跳转后实际所在帧:" << frame_current << endl; while (true) { if(isPlayFlag) { Mat frame;//创建图片数据对象 vcp.read(frame); if (frame.empty()) { break; }//读取为空则结束 namedWindow("显示视频", WINDOW_FREERATIO);//方便调节大小 //获取当前帧数 frame_current = vcp.get(CAP_PROP_POS_FRAMES); cout << "当前帧数:" << frame_current << endl; if (!isDragging) { autoSyncLock = true; //上锁:告知回调这是代码自动刷新 setTrackbarPos("播放进度", "显示视频", (int)frame_current); autoSyncLock = false; //解锁 } string result = getCurrentProgress((int)frame_current, fps) + "/" + getDuration(second_total); result += " fps:" + to_string(fps) + "fps_current:" + to_string(frame_current); putText(frame, result, Point(30, 30), 1, 2, Scalar(0, 0, 255), 2, 8); imshow("显示视频", frame); } int key = waitKey(20); if (key == 27) break; isDragging = false; } vcp.release(); destroyAllWindows(); } void on_trackbar_video(int, void*) { if (autoSyncLock) return; //代码自动更新滑块时,直接跳过回调,阻断递归 isDragging = true;//标记正在拖拽,暂停自动刷新 play_video(vcp,frame_current); } void on_stop_video(int, void*) { isPlayFlag = (isPlay == 1) ? true : false; } /// <summary> /// 滑动条控制视频播放 /// </summary> void QuickDemo::trackbar_video() { vcp.open("D:\\img\\video\\test.avi"); if (!vcp.isOpened()) { cout << "视频打开失败!"; return; } frame_current = 0; int frame_count = vcp.get(CAP_PROP_FRAME_COUNT);//总帧数 //cout << "总帧数:" << frame_count; namedWindow("显示视频", WINDOW_FREERATIO); createTrackbar("播放进度", "显示视频", &frame_current, frame_count, on_trackbar_video, 0); createTrackbar("播放/暂停","显示视频",&isPlay,1,on_stop_video,0); play_video(vcp); }

案例三 滑动条调节图片亮度

在QuickDemo.h中添加

void trackbar_bright();

在主程序main.cpp中调用

QuickDemo qd; qd.trackbar_bright();//调节亮度

在QuickDemo.cpp中编辑函数主体

int brightness = 0; Mat src = imread("D:\\img\\image\\baboon.jpg"); Mat temp = src.clone();//副本 /// <summary> /// 调节像素 /// </summary> /// <param name="a">原像素</param> /// <param name="b">增、减像素</param> /// <returns></returns> int adjustBright(int a,int b) { if (a + b >= 255) return 255; else if (a + b <= 0) return 0; else return a + b; } void onTrackbar(int, void*) { int width = src.rows; int height = src.cols; for (int i = 0;i < width;i++) { for (int j = 0;j < height;j++) { temp.at<Vec3b>(i, j)[0] = adjustBright(src.at<Vec3b>(i, j)[0], brightness); temp.at<Vec3b>(i, j)[1] = adjustBright(src.at<Vec3b>(i, j)[1], brightness); temp.at<Vec3b>(i, j)[2] = adjustBright(src.at<Vec3b>(i, j)[2], brightness); } } imshow("src", temp); } /// <summary> /// 滑动条调节亮度 /// </summary> void QuickDemo::trackbar_bright() { if (src.empty()) { cout << "图片加载失败!";return; } namedWindow("src", 1); createTrackbar("调节亮度", "src", &brightness, 255, onTrackbar,0); setTrackbarMin("调节亮度", "src",-255); showPic("src", src); waitKey(0); destroyAllWindows(); }

文件下载

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

文件下载后,修改文件夹名为"img",存放D盘。

以上不足,请同行、业界大佬批评指正。

相关新闻

  • MySQL数据库基础篇(一):数据库以及Centos 8环境下数据库的安装
  • Agent 架构从单体到分布式:多 Agent 系统怎么拆分和编排部署
  • Drab Commander实战教程:编写你的第一个实时交互功能

最新新闻

  • 3分钟学会配置洛雪音乐:免费获取全网高品质音乐的完整指南
  • Qwen2.5-VL-7B-Instruct-da8w8-torchao-v0.16.0震撼发布:AMD ZenDNN优化的CPU视觉语言模型终极指南
  • LRCGET:如何为离线音乐库批量获取专业级同步歌词的终极指南
  • 如何在AMD EPYC CPU上快速部署gpt-oss-20b-BF16-da8w8-torchao-v0.17.0?超详细环境配置指南
  • 从基础到精通:Mistral-7B-Instruct-v0.2_rai_1.7.1_npu_4K提示词工程完全指南
  • 开发者必备:NVIDIA Kimi-K2.6-Eagle3 API参考手册

日新闻

  • AI推荐结果怎么优化:适合深圳少儿素质培训机构的GEO服务商哪家好?全程零代码SAAS操作
  • RAG 实战教学完全指南
  • 企业级API网关架构深度解析:IBM Microgateway的技术实现与选型指南

周新闻

  • IX9104 PCIe5.0 高速交换芯片@ACP#完整规格 + 应用场景总结
  • Unity游戏集成Coze智能体:实现NPC智能对话与知识库联动
  • SAP EPIC 建行回单查询:从标准类CL_EPIC_EXAMPLE_CN_CCB_GHTD到Z类的5处关键修改

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号