OpenCV计算机视觉开发入门与实践<七>:OpenCV 界面编程之窗口
OpenCV 支持有限的界面编程主要针对窗口、一些控件和一些鼠标事件等比如滑块。有了这些窗口和控件可以更好地展现图像并调节图像的一些参数。这些界面编程主要由 High-level GUI高级图形用户界面模块支持。1.新建窗口并显示在 High-Level GUI 模块中用于新建窗口的函数是 nameWindow同时可以指定窗口的类型。该函数声明如下voidnamedWindow(conststringwinname,intflags);其中参数 winname 表示新建的窗口的名称自己随便取flags 表示窗口的标识一般默认为WINDOW_AUTOSIZEWINDOW_AUTOSIZE 表示窗口大小自动适应图片大小并且不可手动更改WINDOW_NORMAL 表示用户可以改变这个窗口大小WINDOW_OPENGL 表示窗口创建的时候支持 OpenGL。在 High-Level GUI 模块中用于显示窗口的函数是 imshow该函数声明如下voidimshow(conststringwinname,InputArray image);其中参数 winname 表示显示的窗口名可以使用 cv::namedWindow 函数创建窗口若不创建则 imshow 函数将自动创建image 表示窗口中需要显示的图像。根据图像的深度imshow 函数会自动对其进行缩放规则如下1如果图像数据类型是 8U8 位无符号就直接显示。2如果图像数据类型是 16U16 位无符号或 32S32 位有符号整数imshow 函数内部就会自动将每个像素值除以 256 并显示即将原图像素值的范围由0-255X256映射到[0~255]。3如果图像数据类型是 32F32 位浮点数或 64F64 位浮点数imshow 函数内部就会自动将每个像素值乘以 255 并显示即将原图像素值的范围由[01]映射到[0255]注意原图像素值必须归一化。需要注意的是imshow 之后必须有 waitKey 函数否则显示窗口将一闪而过不会驻留屏幕。waitKey 函数声明如下intcv::waitKey(intdelay0);其中参数 delay 表示延时值单位为毫秒默认是 0表示一直等待直到用户按键。如果在指定时间之前没有按任何键就返回-1如果在指定时间之前按键就返回按键的对应值。当 delay≤0 时函数 waitKey 无限地等待一个按键事件或当 delay 是正数的时等待 delay 毫秒。由于操作系统在切换线程之间有一个最短的时间间隔因此该函数不会等待确切精确的延迟毫秒它将至少等待延迟毫秒这取决于当时计算机上运行的其他操作。如果在指定时间之前没有按任何键就返回按键的代码或-1。注意此函数是 HighGUI 模块中唯一可以获取和处理事件的方法因此需要定期调用它以进行正常的事件处理除非 HighGUI 在负责事件处理的环境中使用。另外只有至少创建了一个 HighGUI 窗口并且该窗口处于活动状态该函数才起作用。如果有几个 HighGUI 窗口其中任何一个都可以是活动的。示例程序#includeiostream#includeopencv2/highgui/highgui_c.h#includeopencv2\opencv.hpp#pragmacomment(lib,opencv_world4140d.lib)//引用引入库usingnamespacecv;intmain(){Mat img;imgimread(test.jpg,1);//参数 1图片路径。参数 2:显示原图namedWindow(window1,WINDOW_AUTOSIZE);imshow(window1,img);//在“窗口 1”这个窗口输出图片waitKey(5000);//等待 5 秒程序自动退出。改为 0不自动退出return0;}2.单窗口显示多幅图像前面我们新建的窗口中只显示了一幅图有时在某些场景下比如有多个视频图像如果一个视频图像显示在一个窗口中就会因为窗口过多而显得凌乱。此时需要一个窗口能显示多个视频图像。要达到这个效果原理并不复杂只需要调整每个视频的尺寸大小为窗口的一部分这样多幅图像组合起来正好占满一个窗口。在 OpenCV 中我们可以综合利用坐标变换与 Rect 区域提取来实现单窗口显示多幅图像。首先根据输入图像个数与尺寸确定输入源图像小窗口的构成形态然后设定每个图像小窗口的具体构成包括边界、间隙等最后根据小窗口确定输出图像的尺寸利用缩放函数 resize 进行图像缩放完成单窗口下多幅图像的显示。#includeiostream#includeopencv2/highgui/highgui_c.h#includeopencv2\opencv.hpp#pragmacomment(lib,opencv_world4140d.lib)//引用引入库usingnamespacecv;usingnamespacestd;voidshowManyImages(constvectorMatsrcImages,Size imageSize){intnNumImagessrcImages.size();Size nSizeWindows;if(nNumImages12){coutno more than 12 imagesendl;return;}//根据图像序列数量来确定分割小窗口的形态switch(nNumImages){case1:nSizeWindowsSize(1,1);break;case2:nSizeWindowsSize(2,1);break;case3:case4:nSizeWindowsSize(2,2);break;case5:case6:nSizeWindowsSize(3,2);break;case7:case8:nSizeWindowsSize(4,2);break;case9:nSizeWindowsSize(3,3);break;default:nSizeWindowsSize(4,3);}//设置小图像尺寸、间隙、边界intnShowImageSize200;intnSplitLineSize15;intnAroundLineSize50;//创建输出图像图像大小根据输入源来确定constintimagesHeightnShowImageSize*nSizeWindows.widthnAroundLineSize(nSizeWindows.width-1)*nSplitLineSize;constintimagesWidthnShowImageSize*nSizeWindows.heightnAroundLineSize(nSizeWindows.height-1)*nSplitLineSize;coutimagesWidth imagesHeightendl;MatshowWindowsImages(imagesWidth,imagesHeight,CV_8UC3,Scalar(0,0,0));//提取对应小图像的左上角坐标 x、yintposX(showWindowsImages.cols-(nShowImageSize*nSizeWindows.width(nSizeWindows.width-1)*nSplitLineSize))/2;intposY(showWindowsImages.rows-(nShowImageSize*nSizeWindows.height(nSizeWindows.height-1)*nSplitLineSize))/2;coutposX posYendl;inttempPosXposX;inttempPosYposY;//将每一幅小图像整合成一幅大图像for(inti0;inNumImages;i){//小图像坐标转换if((i%nSizeWindows.width0)(tempPosX!posX)){tempPosXposX;;tempPosY(nSplitLineSizenShowImageSize);}//利用 Rect 区域将小图像置于大图像的相应区域Mat tempImageshowWindowsImages(Rect(tempPosX,tempPosY,nShowImageSize,nShowImageSize));//利用 resize 函数实现图像缩放resize(srcImages[i],tempImage,Size(nShowImageSize,nShowImageSize));tempPosX(nSplitLineSizenShowImageSize);}imshow(showImages,showWindowsImages);}intmain(){//图像源输入vectorMatsrcImage(9);srcImage[0]imread(test.jpg);srcImage[1]imread(test.jpg);srcImage[2]imread(test.jpg);srcImage[3]imread(test.jpg);srcImage[4]imread(test.jpg);srcImage[5]imread(test.jpg);srcImage[6]imread(test.jpg);srcImage[7]imread(test.jpg);srcImage[8]imread(test.jpg);//判断当前 vector 读入的正确性for(inti0;isrcImage.size();i){if(srcImage[i].empty()){coutread errorendl;return-1;}}//调用单窗口显示图像showManyImages(srcImage,Size(147,118));waitKey(0);system(pause);return0;}3. 销毁窗口既然有新建窗口那么也有销毁窗口。在 OpenCV 中销毁窗口时窗口将自动关闭可以通过函数 destroyWindow 和 destroyAllWindows 来实现前者是销毁某一个指定名称的窗口后者是销毁所有新建的窗口。其中函数 destroyWindow 声明如下voiddestroyWindow(constStringwinname);其中参数 winname 是要销毁窗口的名称。destroyWindow 函数更加简单声明如下voiddestroyAllWindows();下面试着来新建三个窗口每个窗口显示 5 秒再分别销毁。#includeopencv2/highgui/highgui_c.h#includeopencv2\opencv.hpp#pragmacomment(lib,opencv_world4140d.lib)//引用引入库usingnamespacecv;#includeiostreamusingnamespacestd;intmain(){//图像源输入vectorMatsrcImage(3);charszName[50];for(inti0;isrcImage.size();i){sprintf_s(szName,%d.jpg,i1);srcImage[i]imread(szName);//读取图像文件if(srcImage[i].empty()){//判断当前 vector 读入的正确性coutread szName errorendl;return-1;}//调用单窗口显示图像namedWindow(szName,WINDOW_AUTOSIZE);imshow(szName,srcImage[i]);//在“窗口 1”这个窗口输出图像waitKey(5000);//等待 5 秒程序自动退出。改为 0不自动退出destroyWindow(szName);}//destroyAllWindows();//cout 所有的窗口已经销毁了 endl;waitKey(0);system(pause);return0;}4.调整窗口大小窗口大小可以手工拖拉窗口边框来调整也可以通过函数方式来调整。调整窗口大小的函数是 resizeWindow声明如下voidresizeWindow(constStringwinname,intwidth,intheight);其中参数 winname 是要调整尺寸的窗口的标题width 是调整后的窗口宽度height 是调整后的窗口高度。但要注意的是新建窗口函数 namedWindow 的第二个参数必须为WINDOW_NORMAL 才可以手动拉动窗口边框来调整大小虽然此时 resizeWindow 依旧可以调整窗口但是图片不会随着窗口大小而改变。#includeopencv2/highgui/highgui_c.h#includeopencv2\opencv.hpp#pragmacomment(lib,opencv_world4140d.lib)//引用引入库usingnamespacecv;#includeiostreamusingnamespacestd;intmain(){vectorMatsrcImage(1);charszName[50];sprintf_s(szName,%d.jpg,1);srcImage[0]imread(szName);if(srcImage[0].empty()){//判断当前 vector 读入的正确性coutread szName errorendl;return-1;}namedWindow(szName,WINDOW_NORMAL);//新建窗口imshow(szName,srcImage[0]);//在窗口显示图片waitKey(2000);intwidth640,height320;resizeWindow(szName,width,height);//调整窗口大小system(pause);return0;}

相关新闻

APMCM数学建模竞赛优秀论文整理:从模型构建到论文写作的实战指南

APMCM数学建模竞赛优秀论文整理:从模型构建到论文写作的实战指南

1. 项目概述:一份迟来的“竞赛地图”如果你正在准备亚太地区大学生数学建模竞赛(APMCM),或者对数学建模竞赛的论文写作感到迷茫,那么你很可能和我几年前一样,在网络上疯狂搜索“优秀论文”、“获奖范文”。…

2026/8/14 6:27:04 阅读更多 →
数学建模从入门到国一:实战路径、核心工具与团队协作全解析

数学建模从入门到国一:实战路径、核心工具与团队协作全解析

1. 从零到一:我的数学建模入门与认知重塑 回想起来,我的数学建模之路始于一次偶然的旁听。当时,看着学长学姐们围在一起,对着电脑屏幕上密密麻麻的公式和图表激烈讨论,我完全是个门外汉,只觉得“数学建模”…

2026/8/14 6:27:04 阅读更多 →
第一讲:算法

第一讲:算法

(写完上一讲,突然发现自己忘记写算法是什么了,好羞愧啊……) 言归正传,这一讲,我们讲算法。 算法是什么 算法是一套明确、有限、可执行的步骤,用来解决特定问题或完成特定任务。 核心要点 …

2026/8/14 6:27:04 阅读更多 →

最新新闻

Agent-study项目教程(06):AI智能写作与反思助手(LangGraph)

Agent-study项目教程(06):AI智能写作与反思助手(LangGraph)

一、理论部分 1. 为什么写作任务更适合用“图(Graph)”而不是“线性链(Chain)” 传统的链式调用通常是单向的:Prompt → LLM → Output。它适合一次性生成类任务,但不擅长表达真实写作过程中的“循环改稿”…

2026/8/14 12:11:56 阅读更多 →
ResidualScaledDotProductAttention详解:Keras-Self-Attention中的残差连接应用

ResidualScaledDotProductAttention详解:Keras-Self-Attention中的残差连接应用

ResidualScaledDotProductAttention详解:Keras-Self-Attention中的残差连接应用 【免费下载链接】keras-self-attention Attention mechanism for processing sequential data that considers the context for each timestamp. 项目地址: https://gitcode.com/gh_…

2026/8/14 12:11:56 阅读更多 →
游戏DLC解锁补丁技术原理与实战指南:从文件替换到本地验证

游戏DLC解锁补丁技术原理与实战指南:从文件替换到本地验证

最近在社区看到不少玩家询问《文明6》DLC的解锁问题,特别是新DLC发布后,如何在不额外购买的情况下体验全部内容。本文将围绕一个技术性话题——如何为《文明6》应用“全DLC解锁补丁”进行详细拆解。请注意,本文旨在从技术原理和操作流程上进行…

2026/8/14 12:11:56 阅读更多 →
Navicat Mac版试用期重置完整指南:三招告别14天倒计时

Navicat Mac版试用期重置完整指南:三招告别14天倒计时

Navicat Mac版试用期重置完整指南:三招告别14天倒计时 【免费下载链接】navicat_reset_mac navicat mac版无限重置试用期脚本 Navicat Mac Version Unlimited Trial Reset Script 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 周四下午&a…

2026/8/14 12:11:56 阅读更多 →
Agent-study项目教程(04):数学建模知识库助手(RAG)

Agent-study项目教程(04):数学建模知识库助手(RAG)

一、理论部分 1. 为什么需要 RAG:解决“知识过期”与“不可溯源” 仅依赖大模型参数内的知识,会遇到两个典型问题: 知识边界:模型未必覆盖你的垂直领域材料(例如一本专业书或内部文档)。不可控与不可溯源&a…

2026/8/14 12:11:55 阅读更多 →
网盘下载慢到怀疑人生?这款开源脚本让九大网盘的直链下载一步到位

网盘下载慢到怀疑人生?这款开源脚本让九大网盘的直链下载一步到位

网盘下载慢到怀疑人生?这款开源脚本让九大网盘的直链下载一步到位 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动…

2026/8/14 12:10:54 阅读更多 →

日新闻

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

临沂网站建设铭镇:深耕本土数字生态,以匠心铸就企业品牌核心竞争力

在这个流量为王、视觉至上的互联网时代,对于临沂乃至整个山东乃至全国的传统中小企业来说,拥有一张精美的“数字名片”早已不再是可选项,而是生存的必答题。每当夜幕降临,沂河两岸灯火辉煌,物流之都的喧嚣逐渐沉淀为对未来的思考。我们常常听到老板们在茶余饭后探讨:为什…

2026/8/14 0:00:26 阅读更多 →
Flutter与OpenHarmony实现剧本杀组队表单开发实战

Flutter与OpenHarmony实现剧本杀组队表单开发实战

1. 项目概述在移动应用开发领域,跨平台框架Flutter因其高效的开发体验和出色的性能表现,已经成为众多开发者的首选。而OpenHarmony作为新兴的操作系统平台,其开放性和灵活性为开发者提供了全新的可能性。本文将聚焦于一个实际应用场景——剧本…

2026/8/14 0:00:26 阅读更多 →
大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

大连网站建设找简维科技:为您打造懂业务更懂用户的数字化转型引擎

在这个数字化浪潮席卷全球的今天,企业想要在激烈的市场竞争中站稳脚跟,拥有一张好看的“数字名片”已经远远不够了。很多老板在刚开始接触互联网业务时,都有一个共同的困惑:为什么我花了钱建的网站,就像是在真空中自嗨?访客进来转了两圈就跑了,线索石沉大海,甚至连客服…

2026/8/14 0:01:27 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/13 2:38:34 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/13 10:41:52 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/13 10:41:51 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/13 10:41:50 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/13 10:41:49 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/13 10:41:49 阅读更多 →