Opencv 導入圖片 Opengl 顯示紋理(含用例代碼)


本篇主要是講使用Opencv導入一副圖片,然后講該副圖片當成紋理顯示在opengl當中。

  1. 首先說如何配置Opencv

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

先在此網站下載opencv,下載之后,它是長這樣的,點擊它,會自動解壓縮成名字為“opencv”的文件夾

接下來進行環境配置:從控制面板開始,按着這個路徑  Control Panel\System and Security\System 來到高級系統設置(advanced system settings)就進入了如下界面:

在系統變量里面找到Path,然后在Value中添加OpenCV的目錄:我的是:C:\Users\Dell\Downloads\opencv\build\x86\vc12\bin。(我的opencv直接保存在了downloads里面)

然后你新建一個VS2015的項目(新建項目方法我就不說了),然后點擊:項目--->屬性--->配置屬性--->VC++目錄----->包含目錄

把下面這些目錄添加進去:

C:\Users\Dell\Downloads\opencv\build\include

C:\Users\Dell\Downloads\opencv\build\include\opencv

C:\Users\Dell\Downloads\opencv\build\include\opencv2

最后大概長這樣:

再在庫目錄中添加這些目錄:

C:\Users\Dell\Downloads\opencv\build\x86\vc12\lib

C:\Users\Dell\Downloads\opencv\build\x86\vc12\staticlib

 注意:你可以發現我這里面用的是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/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM