OpenCV启用OpenGL并用WINDOW_OPENGL窗口显示Mat

起因是steam叠加界面在不启用OpenGL的OpenCV窗口上无法启用,进而无法在全屏时弹出成就、f12截图;尝试过程不易,总结多方经验才最终成功,故记录之,望对看到的人有所帮助。

一、重新编译出支持OpenGL的OpenCV

参考文章:

[转]OpenCV2.4.12 开启OpenGL启用三维可视化支持(不需VIP)

OpenCV2.4.12 开启OpenGL启用三维可视化支持(优快云原文,需VIP)

 对文章描述的补充与修正:

  1. 可以把BUILD_opencv_world勾上,这样就不用管理一大堆lib了,只用opencv_world开头的lib和dll就行了

  2. 文章中提到的python报错其实可以通过取消python相关选项解决(前提是你不需要用到python)

  3.  类似的,Java相关的其实也不必要,取消勾选

  4. test相关的应该也不必要,取消勾选能省一些make时间(图中勾选那个估计也不必要,但本人成功实现功能的版本配置就是如下,保险起见原样截图)

  5. 文章有提到“OpenGL仅支持32位操作系统”:

    opencv官方文档也似乎的确这么说:
    1. OpenCV:OpenGL 互操作性 - OpenCV 计算机视觉库
    2. 但实际上采用64位配置是没问题的,仅支持32位应该是OpenGL库只能用OpenGL32.lib

  6.  对于这一步

    其实在#include <GL/gl.h>之前加#include<Windows.h>就行,因为GL.h可能因为权限不够不能更改

二、用WINDOW_OPENGL属性的OpenCV窗口显示Mat

        1. 通过实现一个小效果,确认OpenGL功能启用(可选)

        参考文章(可以先看看该文章中的代码对应效果能否实现,再进入用OpenGL支持的窗口显示Mat的步骤):

                opengl学习笔记(二):使用OpenCV来创建OpenGL窗口 - feifanren - 博客园

         2. 头文件和OpenGL相关库        
#include<opencv2/opencv.hpp>
#include<opencv2/core/opengl.hpp>
#include<Windows.h>
#include <GL/gl.h>
#include <GL/glu.h>

#pragma comment(lib, "OpenGL32.lib")
#pragma comment(lib, "glu32.lib")

                注意,因为这里同时包括了 #include<opencv2/opencv.hpp>和#include<Windows.h>,可能会遇到“byte不明确”类似的问题,参见:解决启用C++17后byte重定义的问题(byte ambiguous ) - 松山居士 - 博客园

                本人的解决办法是删除所有.h中的using namespace std; 改为使用类似using std::cout;这样的语句(实际上更具体地说,为了方便,把常用的std命名空间里的using声明都放到一个头文件里,这样直接include这个头文件就省事了)

        3.回调函数

                后面在setOpenGlDrawCallback时会将其设置为OpenGL窗口的回调函数。

static void on_image_update_clbk(void* param) {
	cv::ogl::Texture2D* backgroundTex = (cv::ogl::Texture2D*)param;
	glEnable(GL_TEXTURE_2D);
	backgroundTex->bind();
	cv::ogl::render(*backgroundTex);
	glDisable(GL_TEXTURE_2D);
}
        4.绘制过程的总函数

                本人是将其设为一个类里的成员函数的,下面的代码对应修改成了外部函数,若有需要可自行更改传参模式

                注意,若之前已存在同名非WINDOW_OPENGL窗口,则WINDOW_OPENGL在此处并不会成功启用

                另外,setOpenGlContext应在与OpenGL相关的操作前调用,如Texture2D的转换甚至是定义(不过Texture2D指针就无关了)

cv::ogl::Texture2D* tex=nullptr;
void showWindow(Mat& finalShow)
{
    string winName="Your Window Name";// 可设为你自己想要的窗口名
	namedWindow(winName, WINDOW_OPENGL);// 注意,若存在同名窗口,则WINDOW_OPENGL在此处并不会成功启用

    // 若需要全屏可以启用
	//if (FULL_SCREEN) {
	//	setWindowProperty(winName, WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
	//}

    // 将openGL上下文设置为对应窗口
	setOpenGlContext(winName);

    // 将Mat转换为Texture2D
	//cv::ogl::Texture2D tex(finalShow,1); // 也可以改为使用这行而把下面的if else注释掉,如此还需要把setOpenGlDrawCallback时的tex改为传入&tex。理论上性能会降低,但实际似乎并无大区别
	if (tex == nullptr) {
		tex = new ogl::Texture2D(finalShow,1);
	}
	else {
		tex->copyFrom(finalShow);// 易错点!此处不能使用convertToTexture2D
	}
	
    // 防止低分辨率图像自动放大时的抗锯齿导致的模糊
	GLuint id=tex->texId();
	glBindTexture(GL_TEXTURE_2D, id);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    // 设置回调函数
	setOpenGlDrawCallback(winName, on_image_update_clbk, tex);

    // 设置鼠标回调,onMouse是自己写的,若不需要鼠标操控则不需要启用这行
	//setMouseCallback(winName, onMouse, this);

    // 不加下面这行会一直卡在第一帧
	updateWindow(winName);

    // 会降低一些帧数,但若没有其他的消息处理调用的话会导致无法显示
    waitKey(1);
}
        5.(附)waitKey的替代方案

                在主循环调用即可,性能比waitKey好多了,而且也解决了负载较重时鼠标回调延迟的问题。

// 用于强制处理消息队列
void processMessages()
{
	MSG msg; // 定义一个 MSG 结构体,用于存储消息
	while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
	{
		TranslateMessage(&msg); // 将虚拟键消息转换为字符消息
		DispatchMessage(&msg);  // 将消息发送到窗口过程函数进行处理
	}
}

### C++ OpenCV 显示提示窗口 为了创建一个带有提示信息的窗口,在C++中使用OpenCV可以通过`cv::namedWindow()`函数来定义窗口名称,并通过`cv::imshow()`显示图像的同时利用其他GUI组件或者自定义绘制文字的方式实现。 当希望向用户展示特定消息时,一种常见做法是在图像上绘制文本。这可通过`putText`函数完成: ```cpp #include <opencv2/opencv.hpp> using namespace cv; using namespace std; int main(){ // 创建一张空白图像作为背景 Mat img(480, 640, CV_8UC3, Scalar(255, 255, 255)); // 设置字体参数 putText(img, "This is a prompt message.", // 文本字符串 Point(100, 200), // 开始坐标 FONT_HERSHEY_SIMPLEX, // 字体类型 1.0, // 缩放因子 Scalar(0, 0, 255), // 颜色 (BGR) 2 // 笔画粗细程度 ); namedWindow("Prompt Window", WINDOW_AUTOSIZE); imshow("Prompt Window", img); waitKey(0); // 等待按键事件关闭窗口 destroyAllWindows(); return 0; } ``` 上述代码片段展示了如何在一个白色背景下创建一个包含红色提示信息的窗口[^3]。如果想要支持更复杂的交互功能,则可能需要考虑集成额外的图形界面库(如Qt),因为纯OpenCV对于复杂UI的支持较为有限。 #### 特殊情况下的OpenGL支持 值得注意的是,某些情况下可能会涉及到对OpenGL特性的需求。此时可以在调用`namedWindow`的时候指定标志位为`WINDOW_OPENGL`以启用此特性: ```cpp namedWindow("OpenGL Supported Prompt Window", WINDOW_OPENGL | WINDOW_AUTOSIZE); ``` 这样做的前提是编译环境已正确配置好相应的依赖项并且硬件设备兼容该模式[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值