zoukankan      html  css  js  c++  java
  • Opencv 导入图片 Opengl 显示纹理(含用例代码)

    本篇主要是讲使用Opencv导入一副图片,然后讲该副图片当成纹理显示在opengl当中。

    1. 首先说如何配置Opencv

    我的硬件环境是: Windows10+Visual Studio 2015+opencv3.0

    先在此网站下载opencv,下载之后,它是长这样的,点击它,会自动解压缩成名字为“opencv”的文件夹

    接下来进行环境配置:从控制面板开始,按着这个路径  Control PanelSystem and SecuritySystem 来到高级系统设置(advanced system settings)就进入了如下界面:

    在系统变量里面找到Path,然后在Value中添加OpenCV的目录:我的是:C:UsersDellDownloadsopencvuildx86vc12in。(我的opencv直接保存在了downloads里面)

    然后你新建一个VS2015的项目(新建项目方法我就不说了),然后点击:项目--->属性--->配置属性--->VC++目录----->包含目录

    把下面这些目录添加进去:

    C:UsersDellDownloadsopencvuildinclude

    C:UsersDellDownloadsopencvuildincludeopencv

    C:UsersDellDownloadsopencvuildincludeopencv2

    最后大概长这样:

    再在库目录中添加这些目录:

    C:UsersDellDownloadsopencvuildx86vc12lib

    C:UsersDellDownloadsopencvuildx86vc12staticlib

     注意:你可以发现我这里面用的是x86架构,其实opencv里面还给了x64架构。这主要取决于你的项目用的是什么架构,可以看这里来判断

    最后一步:

    点击链接器---> 输入---->附加依赖项中加入:

    opencv_ts300.lib; opencv_world300.lib

    至此 opencv就配置好了。你当然也要配置opengl,但是这里我就不说了。

    2. 图片作为纹理在opengl中显示

    先把要用的资源图片放在你VS项目中的目录中,与cpp文件一个目录下面。

    请复制一下代码:

    #include<gl/glut.h>
    #include <opencv.hpp>
    using namespace cv;
    
    //OpenCV读取图像
    Mat I = imread("ntulogo.bmp");
    //设置长宽
    int width = I.cols;
    int height = I.rows;
    //设置图像指针
    GLubyte* pixels;
    
    GLuint load_texture()
    {
        //OpenGL纹理用整型数表示
        GLuint texture_ID;
    
        //获取图像指针
        int pixellength = width*height * 3;
        pixels = new GLubyte[pixellength];
        memcpy(pixels, I.data, pixellength * sizeof(char));
        imshow("OpenCV", I);
    
        //将texture_ID设置为2D纹理信息
        glGenTextures(1, &texture_ID);
        glBindTexture(GL_TEXTURE_2D, texture_ID);
        //纹理放大缩小使用线性插值
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        //纹理水平竖直方向外扩使用重复贴图
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        //纹理水平竖直方向外扩使用边缘像素贴图(与重复贴图二选一)
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    
        //将图像内存用作纹理信息
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);
    
        free(pixels);
        return texture_ID;
    }
    
    void display()
    {
        // 清除屏幕
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //获取纹理对象
        GLuint image = load_texture();
    
        //重新设置OpenGL窗口:原点位置为左上角,x轴从左到右,y轴从上到下,坐标值与像素坐标值相同
        glViewport(0, 0, (GLsizei)width, (GLsizei)height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(0, width, height, 0);
    
        //显示纹理
        glEnable(GL_TEXTURE_2D);    //允许使用纹理
        glBindTexture(GL_TEXTURE_2D, image);    //选择纹理对象
    
                                                //原始完全填充四边形
        glBegin(GL_POLYGON);    //设置为多边形纹理贴图方式并开始贴图
        glTexCoord2f(0.0f, 0.0f); glVertex2f(0, 0);    //纹理左上角对应窗口左上角
        glTexCoord2f(0.0f, 1.0f); glVertex2f(0, height);    //纹理左下角对应窗口左下角
        glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);    //纹理右下角对应窗口右下角
        glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0);    //纹理右上角对应窗口右上角
        glEnd();    //结束贴图*/
    
                    /*//三角形
                    glBegin(GL_POLYGON);
                    glTexCoord2f(0.0f, 0.0f); glVertex2f(0, 0);
                    glTexCoord2f(0.0f, 1.0f); glVertex2f(0, height);
                    glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
                    glEnd();*/
    
                /*    //多边形
                    glBegin(GL_POLYGON);
                    glTexCoord2f(0, 0); glVertex2f(0, 0);
                    glTexCoord2f(0, 1); glVertex2f(0, height/3);
                    glTexCoord2f(1, 1); glVertex2f(width/4, height/3);
                    glTexCoord2f(1, 0); glVertex2f(width/4, 0);
                    glTexCoord2f(0.0f, 0.5f); glVertex2f(0, height/2);
                    glEnd();*/
    
                    /*//任意变换
                    glBegin(GL_POLYGON);
                    glTexCoord2f(0.0f, 0.0f); glVertex2f(width/4, height/4);
                    glTexCoord2f(0.0f, 1.0f); glVertex2f(0, height);
                    glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height*2/3);
                    glTexCoord2f(1.0f, 0.0f); glVertex2f(width*4/5, 50);
                    glEnd();*/
    
                    //边缘贴图效果
                    /*glBegin(GL_POLYGON);
                    glTexCoord2f(0.0f, 0.0f); glVertex2f(0, 0);
                    glTexCoord2f(0.0f, 2.0f); glVertex2f(0, height);
                    glTexCoord2f(2.0f, 2.0f); glVertex2f(width, height);
                    glTexCoord2f(2.0f, 0.0f); glVertex2f(width, 0);
                    glEnd();*/
    
        glDisable(GL_TEXTURE_2D);    //禁止使用纹理
    
                                    //双缓存交换缓存以显示图像
        glutSwapBuffers();
    }
    
    void main(int argc, char** argv)
    {
        //初始化GL
        glutInit(&argc, argv);
        //设置显示参数(双缓存,RGB格式)
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        //设置窗口尺寸:width*height
        glutInitWindowSize(width, height);
        //设置窗口位置:在屏幕左上角像素值(100,100)处
        glutInitWindowPosition(100, 100);
        //设置窗口名称
        glutCreateWindow("OpenGL");
        //显示函数,display事件需要自行编写
        glutDisplayFunc(display);
    
        //重复循环GLUT事件
        glutMainLoop();
    }

    最后你会看到这个结果:

    3. 再说几个小问题

    如果在opengl中,你在使用贴纹理之前,有使用过glColor函数,就会影响到接下来的贴图,例如:我前面使用过了glColor3f(1,0,0).那么我的纹理图就会变成这样:

    所以,需要在纹理贴图之前,写一句glColor3f(1,1,1)

    其次如果你的项目中用到了光照,那这个光照可能会影响到纹理的显示,就会变暗。

    解决方法是在画纹理的前后加上,关闭光照和打开光照这两句话,即:

    glDisable(GL_LIGHTING);

    glEnable(GL_LIGHTING);

     还有不懂之处,请参考一下参考网站

    reference:

    1. https://zhuanlan.zhihu.com/p/24714986?refer=ry000

    2. http://blog.csdn.net/lanergaming/article/details/48689841

    3. https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/06%20Textures/

  • 相关阅读:
    yii2 gii 命令行自动生成控制器和模型
    控制器中的方法命名规范
    Vue Property or method "" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based
    IDEA插件:GsonFormat
    Spring Boot : Access denied for user ''@'localhost' (using password: NO)
    Typora添加主题
    Git基础命令图解
    Java Joda-Time 处理时间工具类(JDK1.7以上)
    Java日期工具类(基于JDK1.7版本)
    Oracle SQL Developer 连接Oracle出现【 状态: 失败 -测试失败: ORA-01017: invalid username/password; logon denied】
  • 原文地址:https://www.cnblogs.com/lws520/p/6773910.html
Copyright © 2011-2022 走看看