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

十七、OpenCV中HighGUI模块的介绍和使用

文章目录

    • 一、使用cv::namedWindow()创建一个窗口
    • 二、通过cv::imshow()显示图像
    • 三、鼠标事件的使用
    • 四、键盘事件的使用
    • 五、滑动条的使用

一、使用cv::namedWindow()创建一个窗口

  cv::namedWindow() 是 OpenCV 中用于创建一个显示窗口的函数,它通常与 cv::imshow() 一起使用,用于显示图像或视频帧。它属于 HighGUI 模块,是 OpenCV 提供的最基本 GUI 接口之一。

函数原型:

void cv::namedWindow(const std::string& winname, int flags = cv::WINDOW_AUTOSIZE);

参数说明:
在这里插入图片描述
窗口模式(flags):
在这里插入图片描述
注意:只有在 WINDOW_NORMAL 模式下,用户才能手动改变窗口大小。其他模式如 AUTOSIZE 下,窗口会随图像大小自动变化。

使用示例
示例 1:创建并显示图像窗口

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) {printf("图片加载失败!\n");return -1;}// 创建一个自动适应图像大小的窗口namedWindow("My Window", WINDOW_AUTOSIZE);// 在窗口中显示图像imshow("My Window", img);// 等待按键waitKey(0);return 0;
}

示例 2:创建一个可调整大小的窗口

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;// 创建一个可缩放的窗口namedWindow("Resizable Window", WINDOW_NORMAL);imshow("Resizable Window", img);waitKey(0);return 0;
}

此时你可以拖动窗口边缘改变大小。

示例 3:与滑动条结合使用

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;namedWindow("Brightness Control", WINDOW_NORMAL);int alpha = 50;createTrackbar("Brightness", "Brightness Control", &alpha, 100);while (true){Mat adjusted;img.convertTo(adjusted, -1, 1, alpha - 50);imshow("Brightness Control", adjusted);if (waitKey(30) == 27) break; // 按下 ESC 退出}return 0;
}

二、通过cv::imshow()显示图像

  cv::imshow() 是 OpenCV 中最常用的图像显示函数之一,用于在一个窗口中显示图像。
它通常与 cv::namedWindow() 和 cv::waitKey() 搭配使用。
在语言模型中,编码器和解码器都是由一个个的 Transformer 组件拼接在一起形成的。

函数原型:

void cv::imshow(const std::string& winname, cv::InputArray mat);

参数说明:
在这里插入图片描述
函数作用:

  • 在指定名称的窗口中显示一张图像。
  • 如果窗口不存在,OpenCV 会自动创建一个 WINDOW_AUTOSIZE 类型的窗口。
  • 显示内容会一直保留,直到:显示新的内容(再次调用 imshow()),或者窗口被关闭(cv::destroyWindow())。

基本使用示例
示例 1:显示一张图片

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg"); // 读取图片if (img.empty()) {printf("无法读取图像!\n");return -1;}imshow("显示窗口", img);  // 显示图像waitKey(0);               // 等待按键(0 表示无限等待)return 0;
}

waitKey() 是必须的,否则窗口会一闪而过。waitKey() 会触发窗口事件处理(刷新显示、响应鼠标等)。

示例 2:手动创建可缩放窗口

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;namedWindow("可调整大小窗口", WINDOW_NORMAL); // 可缩放窗口imshow("可调整大小窗口", img);waitKey(0);return 0;
}

示例 3:显示灰度图

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat gray = imread("test.jpg", IMREAD_GRAYSCALE); // 灰度读取imshow("灰度图", gray);waitKey(0);return 0;
}

示例 4:显示处理过程中的多张图像

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;Mat gray, edges;cvtColor(img, gray, COLOR_BGR2GRAY);Canny(gray, edges, 100, 200);imshow("原图", img);imshow("灰度图", gray);imshow("边缘检测", edges);waitKey(0);return 0;
}

示例 5:实时显示视频帧(如摄像头)

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{VideoCapture cap(0); // 打开摄像头if (!cap.isOpened()) {printf("无法打开摄像头!\n");return -1;}while (true){Mat frame;cap >> frame;if (frame.empty()) break;imshow("摄像头实时画面", frame);// 按下 ESC 键退出if (waitKey(30) == 27) break;}return 0;
}

示例6:在窗口上实时更新图像

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;namedWindow("动态显示", WINDOW_AUTOSIZE);for (int i = 0; i < 100; i++){Mat bright;img.convertTo(bright, -1, 1, i - 50); // 动态调节亮度imshow("动态显示", bright);if (waitKey(30) == 27) break; // ESC 退出}return 0;
}

三、鼠标事件的使用

  OpenCV 的鼠标事件(Mouse Events)是图像交互中非常实用的一部分。通过它,你可以在显示窗口中响应鼠标点击、拖拽、移动等操作,从而实现图像标注、ROI选区、目标跟踪等功能。

函数原型:

void cv::setMouseCallback(const std::string& winname,cv::MouseCallback onMouse,void* userdata = nullptr
);

参数说明:
在这里插入图片描述
回调函数类型定义:

typedef void (*MouseCallback)(int event,        // 鼠标事件类型int x,            // 鼠标x坐标int y,            // 鼠标y坐标int flags,        // 组合键标志(如Ctrl/Shift等)void* userdata    // 用户数据指针
);

常用鼠标事件类型(event):
在这里插入图片描述
组合键标志(flags):
在这里插入图片描述
示例代码
打印鼠标坐标:

#include <opencv2/opencv.hpp>
using namespace cv;// 鼠标回调函数
void onMouse(int event, int x, int y, int flags, void* userdata)
{if (event == EVENT_MOUSEMOVE){printf("鼠标移动到 (%d, %d)\n", x, y);}else if (event == EVENT_LBUTTONDOWN){printf("左键按下: (%d, %d)\n", x, y);}else if (event == EVENT_RBUTTONDOWN){printf("右键按下: (%d, %d)\n", x, y);}
}int main()
{Mat img = Mat::zeros(400, 600, CV_8UC3);namedWindow("鼠标演示", WINDOW_AUTOSIZE);// 绑定鼠标事件setMouseCallback("鼠标演示", onMouse, nullptr);imshow("鼠标演示", img);waitKey(0);return 0;
}

鼠标绘制矩形(ROI选择):

#include <opencv2/opencv.hpp>
using namespace cv;struct RectData {Point start, end;bool drawing = false;
};void onMouse(int event, int x, int y, int flags, void* userdata)
{RectData* data = reinterpret_cast<RectData*>(userdata);if (event == EVENT_LBUTTONDOWN) {data->drawing = true;data->start = Point(x, y);}else if (event == EVENT_MOUSEMOVE && data->drawing) {data->end = Point(x, y);}else if (event == EVENT_LBUTTONUP) {data->drawing = false;data->end = Point(x, y);printf("选取区域:(%d,%d) - (%d,%d)\n", data->start.x, data->start.y, data->end.x, data->end.y);}
}int main()
{Mat img = Mat::zeros(400, 600, CV_8UC3);Mat temp;RectData data;namedWindow("ROI绘制", WINDOW_AUTOSIZE);setMouseCallback("ROI绘制", onMouse, &data);while (true){img.copyTo(temp);if (data.drawing)rectangle(temp, data.start, data.end, Scalar(0, 255, 0), 2);imshow("ROI绘制", temp);if (waitKey(30) == 27) break; // 按ESC退出}return 0;
}

四、键盘事件的使用

  在 OpenCV 中确实有按键事件(Keyboard Events),不过它不像鼠标事件那样需要回调函数,而是通过函数 cv::waitKey() 实现的。

核心函数:cv::waitKey()
函数原型:

int cv::waitKey(int delay = 0);

参数说明:
在这里插入图片描述
返回值:

  • 如果用户按下某个键,则 waitKey() 返回该键的 ASCII 码值。
  • 如果在 delay 毫秒内未检测到按键,则返回 -1。

原理说明
cv::waitKey() 其实有两个功能:

  1. 处理窗口刷新事件(否则 imshow() 的内容不会更新)
  2. 监听键盘输入事件

也就是说,不调用 waitKey(),图像窗口不会响应任何事件,包括显示更新和鼠标交互!

基本使用示例
示例 1:等待按键退出

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");imshow("图像窗口", img);// 等待任意按键waitKey(0);return 0;
}

当你按任意键时,程序才会退出。

示例 2:定时刷新 + 检测按键

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{VideoCapture cap(0);if (!cap.isOpened()) return -1;while (true){Mat frame;cap >> frame;imshow("摄像头", frame);int key = waitKey(30);  // 等待30msif (key == 27) break;   // ESC退出}return 0;
}

每隔 30ms 刷新一次图像,并检查用户是否按下 ESC 键。这是典型的 OpenCV 实时显示循环写法。

常见按键值(ASCII码)
在这里插入图片描述
示例:按键控制显示行为

#include <opencv2/opencv.hpp>
using namespace cv;int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;imshow("按键控制", img);while (true){int key = waitKey(0);if (key == 27) // ESCbreak;else if (key == 's' || key == 'S'){imwrite("output.jpg", img);printf("图片已保存!\n");}else if (key == 'g' || key == 'G'){Mat gray;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("按键控制", gray);printf("切换为灰度图\n");}}return 0;
}

五、滑动条的使用

  在 OpenCV 中,滑动条其实就是一个 GUI 控件,可以用来实时调节参数(例如阈值、亮度、对比度、滤波半径等),而“滚动条”和“开关”在 OpenCV 中是通过滑动条或按钮模拟实现的。
函数原型:

int cv::createTrackbar(const std::string &trackbarname,const std::string &winname,int *value,int count,TrackbarCallback onChange = 0,void *userdata = 0
);

参数说明:
在这里插入图片描述
回调函数类型:

typedef void (*TrackbarCallback)(int pos, void* userdata);
  • pos:当前滑动条位置
  • userdata:用户自定义数据

滑动条基本示例:

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;void onTrack(int pos, void* userdata)
{Mat* img = reinterpret_cast<Mat*>(userdata);Mat dst;img->convertTo(dst, -1, 1, pos - 50); // 调整亮度imshow("滑动条示例", dst);
}int main()
{Mat img = imread("test.jpg");if (img.empty()) return -1;namedWindow("滑动条示例", WINDOW_AUTOSIZE);int slider = 50; // 初始值createTrackbar("Brightness", "滑动条示例", &slider, 100, onTrack, &img);imshow("滑动条示例", img);waitKey(0);return 0;
}
http://www.dtcms.com/a/528050.html

相关文章:

  • 【JVM】详解 编译器原理与优化技术
  • 良好形象的重要性----反思
  • kali抓包流量
  • Python 正则表达式深度解析与实战指南
  • 开源 Linux 服务器与中间件(十二)FRP内网穿透应用
  • 石家庄网站建设王道下拉棒wordpress 类似
  • 基于AT89C52单片机的计算器设计与仿真
  • AI研究-112 DeepSeek-OCR 发展背景 走红原因 新型任务与潜在研究方向 详细分析 附最小运行测试
  • STC32G144K246,高速PWM@240Mhz 运行测试
  • OpenHarmony轻量级内核LiteOS-M技术详解与应用实践
  • hive自定义函数
  • 做新媒体每天必看的网站wordpress exif
  • Elasticsearch从入门到进阶——分布式特性
  • Elasticsearch并发更新冲突问题与解决
  • 数据结构14:查找
  • 怎样做网站模板wordpress用阿里云oss
  • Spring Java配置:告别XML新时代
  • Flutter 异步进阶:Isolate 与 compute 的性能优化实践
  • 太原网站建设模板网页制作的公司怎么注册
  • Linux拓展
  • 亚马逊云渠道商:本地SSD缓存如何保障数据安全?
  • seo外包公司排名深圳网站优化最好的方法
  • SQL优化详解与案例、以及索引失效场景;
  • llama.cpp:Linux_x86端测试Qwen2.5-Omni
  • Java-160 MongoDB副本集部署实战 单机三实例/多机同法 10 分钟起集群 + 选举/读写/回滚全流程
  • 使用RedisTemplate设计一个消息队列?
  • 海龟交易系统R
  • 【攻防实战】Redis未授权RCE联动metasploit打穿三层内网(上)
  • 织梦网站图片修改不了wordpress模板开发 2016
  • .Net Framework 3.5下载安装教程(附安装包)