• 在本站开通年度VIP,无限制下载本站资源和阅读本站文章

  • 本站会放置Google广告用于维持域名以及网站服务器费用。

  • 欢迎大家交换友链,可在https://www.stubbornhuang.com/申请友情链接进行友链交换申请!

  • 本站由于前段时间遭受到大量临时和国外邮箱注册,所以对可注册的邮箱类型进行了限制!

  • 感谢大家访问本站,希望本站的内容可以帮助到大家!

  • 问题反馈可发送邮件到stubbornhuang@qq.com

  • 计算机图形学与计算几何经典必备书单整理,下载链接可参考:https://www.stubbornhuang.com/1256/

  • 如果觉得本站的内容有帮助,可以考虑打赏博主哦!

  • 工资「喂饱肚子」,副业「养活灵魂」!

OpenCV | OpenGL – OpenCV的cv::mat转换为OpenGL的GL_TEXTURE_2D纹理数据

C++ 发布于2023-06-19 阅读 4,196次 0次评论 0次点赞 本文共4000个字,阅读需要10分钟。

1 OpenCV的cv::Mat转换OpenGLGL_TEXTURE_2D纹理数据

在有些场景下我们需要将OpenCV处理之后的cv::Mat转为OpenGL的GL_TEXTURE_2D类型的纹理数据,比如说使用OpenCV读取图片文件作为OpenGL的纹理使用。

https://gist.github.com/zhangzhensong/03f67947c22acb5ee922我找到了如下的代码:

// don't forget to include related head files
void BindCVMat2GLTexture(cv::Mat& image, GLuint& imageTexture)
{
   if(image.empty()){
      std::cout << "image empty" << std::endl;
  }else{
      //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
      glGenTextures(1, &imageTexture1);
      glBindTexture(GL_TEXTURE_2D, imageTexture1);

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // Set texture clamping method
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

      cv::cvtColor(image, image, CV_RGB2BGR);

      glTexImage2D(GL_TEXTURE_2D,         // Type of texture
                        0,                   // Pyramid level (for mip-mapping) - 0 is the top level
            GL_RGB,              // Internal colour format to convert to
                        image.cols,          // Image width  i.e. 640 for Kinect in standard mode
                        image.rows,          // Image height i.e. 480 for Kinect in standard mode
                        0,                   // Border width in pixels (can either be 1 or 0)
            GL_RGB,              // Input image format (i.e. GL_RGB, GL_RGBA, GL_BGR etc.)
            GL_UNSIGNED_BYTE,    // Image data type
            image.ptr());        // The actual image data itself
    }
} 

然后我又在Spout2仓库中SpoutGL类中找到了相关代码,然后进行了改进和结合,封装了如下的工具函数

GLuint ConvertCVMatToGLTexture(const cv::Mat& image)
{
    // 图片判空
    if (image.empty()) 
    {
        std::cout << "image empty" << std::endl;
        return;
    }

    // 图片深拷贝
    cv::Mat image_copy;
    image.copyTo(image_copy);

    int image_height = image_copy.rows;
    int image_width = image_copy.cols;

    // cv::Mat转换为GL_TEXTURE_2D
    unsigned int texture_id;
    glGenTextures(1, &texture_id);

    GLint texturebinding;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &texturebinding);

    glBindTexture(GL_TEXTURE_2D, texture_id);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image_width, image_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, texturebinding);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glBindTexture(GL_TEXTURE_2D, texture_id);
    // 第一种
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, image_copy.data);

    // 第二种
    //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image_width, image_height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_copy.data);
    glBindTexture(GL_TEXTURE_2D, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    return texture_id;
}

上述函数形参是cv::Mat,然后函数返回值为GL_TEXTURE_2D的纹理id。

测试代码如下:

#include <iostream>

#include "opencv2/opencv.hpp"
#include <GL\GL.h>

GLuint ConvertCVMatToGLTexture(const cv::Mat& image)
{
    // 图片判空
    if (image.empty())
    {
        std::cout << "image empty" << std::endl;
        return;
    }

    // 图片深拷贝
    cv::Mat image_copy;
    image.copyTo(image_copy);

    int image_height = image_copy.rows;
    int image_width = image_copy.cols;

    // cv::Mat转换为GL_TEXTURE_2D
    unsigned int texture_id;
    glGenTextures(1, &texture_id);

    GLint texturebinding;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &texturebinding);

    glBindTexture(GL_TEXTURE_2D, texture_id);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image_width, image_height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, texturebinding);

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glBindTexture(GL_TEXTURE_2D, texture_id);
    // 第一种
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, GL_RGB, GL_UNSIGNED_BYTE, image_copy.data);

    // 第二种
    //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image_width, image_height, 0, GL_RGB, GL_UNSIGNED_BYTE, image_copy.data);
    glBindTexture(GL_TEXTURE_2D, 0);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

    return texture_id;
}

int main()
{
    std::string image_path = "../../resource/final.png";
    cv::Mat image = cv::imread(image_path);

    GLuint texture_id = ConvertCVMatToGLTexture(image);


    return 0;
}

参考链接

https://gist.github.com/zhangzhensong/03f67947c22acb5ee922

欢迎扫码关注我的微信公众号,及时获取文章更新

微信公众号二维码

本文作者:StubbornHuang

版权声明:本文为站长原创文章,如果转载请注明原文链接!

原文标题:OpenCV | OpenGL – OpenCV的cv::mat转换为OpenGL的GL_TEXTURE_2D纹理数据

原文链接:https://www.stubbornhuang.com/2661/

发布于:2023年06月19日 17:53:25

修改于:2023年06月19日 17:53:43

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

文章末尾
上一篇
C++ - 根据给定分隔符分割字符串
C++
下一篇
Windows编译Spout2以及配置Spout2开发环境
C++
当前分类随机文章推荐

发表评论

您必须 [ 登录 ] 才能发表留言!

关注我们的公众号

微信公众号