OpenCV 滑动条

📅 2026/7/13 16:01:22
OpenCV 滑动条
案例一、通过滑动条修改高、低阈值控制边缘检测在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 nameseconds/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 nameframe_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 (minute10) ? to_string(minute) : 0 to_string(minute); string sec_str (second10)? 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 namevcp/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 namevcp视频数据/param /// param nameframe_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 namea原像素/param /// param nameb增、减像素/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.atVec3b(i, j)[0] adjustBright(src.atVec3b(i, j)[0], brightness); temp.atVec3b(i, j)[1] adjustBright(src.atVec3b(i, j)[1], brightness); temp.atVec3b(i, j)[2] adjustBright(src.atVec3b(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盘。以上不足请同行、业界大佬批评指正。