1. 程式人生 > >使用OpenGL顯示雙目視覺三維重構效果

使用OpenGL顯示雙目視覺三維重構效果

cmd_window

bm_3d_gl

sgbm_3d_gl

sgbm_fullDP_3d_gl

上一篇筆記中使用Matlab初步顯示了雙目視覺重構出的環境三維效果圖,不過並沒有加上紋理資訊。在OpenCV中文論壇裡,大象的帖子(http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=8722&sid=02986dcffb5ebcedf299833e7cbf457c)給出了利用OpenGL顯示視差資料的三維點雲圖,這是一個學習OpenGL和OpenCV混合程式設計的好帖子,裡面的討論跟帖也很有參考意義,我下面的程式碼也是參考這個帖子的,感謝大象和論壇上的朋友們。在大象的帖子中,所顯示的三維點雲是基於視差圖來繪製的,視差越大,點雲就越靠近攝像機的近面,但要顯示環境的三維重構資料,則還需結合攝像機定標和雙目校正(cvStereoRectify)獲得的引數來計算出三維座標(cvReprojectImageTo3D);另一方面,要動態顯示實時的三維重構資料,還需要用到一個 FreeGlut (

http://freeglut.sourceforge.net/docs/api.php#WindowCallback)的函式庫,因為原本的 glut 函式庫的 glutMainLoop 在呼叫之後就不會返回、實現不了迴圈,而 FreeGlut 則有一個 glutMainLoopEvent 函式,每迴圈一次就會返回。下面結合著程式碼裡分步講述,主要參考來源包括:

[2] 李穎 等. OpenGL函式與範例解析手冊. 國防工業出版社, 2002年1月.

[3] Edward Angel 著. 段菲 譯. OpenGL程式設計基礎(第3版). 清華大學出版社, 2008年3月.

一、FreeGlut的安裝

(1)在 VC 的安裝目錄(例如 D:/Microsoft Visual Studio 9.0/VC)新建一個資料夾 freeglut;

(2)將下載的 FreeGlut (freeglut 2.6.0‑3 for MSVC)解壓後,把 include 和 lib 資料夾複製到資料夾 freeglut,把 freeglut.dll 複製到系統資料夾 system32;

(3)在 VS2008 的 Tools –> Options 的 VC++ Directories 中加入 freeglut 的 include 和 lib 路徑;

(4)在專案 Properties 的 Link –> input 中加入 opengl32.lib glu32.lib freeglut.lib;

  1. #include "stdafx.h"
  2. #include "MemLeakDetect.h"    // 記憶體洩漏檢測工具,下載地址:http://www.codeproject.com/KB/cpp/MemLeakDetect.aspx
  3. #include <vector>
  4. #include <string>
  5. #include <algorithm>
  6. #include <iostream>
  7. #include <ctype.h>
  8. #include <stdarg.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <GL/freeglut.h>
  13. #include "cv.h"
  14. #include "highgui.h"
  15. #include "camerads.h"
  16. usingnamespace std;  
  17. usingnamespace cv;  
  18. // Detect Memory Leaks or comment    
  19. #ifdef _DEBUG   
  20. CMemLeakDetect memLeakDetect;     
  21. #endif 
  22. enum { STEREO_BM=0, STEREO_SGBM=1 };  
  23. int alg = STEREO_BM;  
  24. int stereo_rectify = 1, adaptThresh = 1;      
  25. int SADWindowSize = 15, numberOfDisparities = 64, SADWS_alpha = 8, MaxDisp_beta = 4,  
  26.     uniqRatio = 25, thresRatio = 60;  
  27. int saveFrames = 1;  
  28. bool fullDP = false;  
  29. double m_ObjectWidth[10] = {0.0};        // 目標寬度                    
  30. double m_ObjectHeight[10] = {0.0};    // 目標高度
  31. double m_ObjectDisparity[10] = {0.0};        // 視差
  32. double m_ObjectDistance[10] = {0.0};                    // 距離
  33. char img1name[100], img2name[100], dispImgName[100], dispDataName[100];  
  34. //---OpenGL
  35. float imgdata[500][500][3];    // 存放三維座標資料
  36. float texture[500][500][3]; // 存放紋理資料
  37. int width=0, height=0, rx = 0, ry = 0;  
  38. int eyex = 115, eyez = 115, atx = 100, atz = 50;  
  39. float scalar=1;        //scalar of converting pixel color to float coordinates

二、OpenGL 響應函式

在大象帖子的跟帖中, 綜合了一小段程式碼,隨著滑鼠移動,可以從多個視角觀看生成的三維點雲圖,我在其基礎上做了修改。為了與OpenCV迴圈同步,去掉了滑鼠移動的響應函式( 的程式碼裡用了定時器),改為使用 OpenCV 的 TrackBar 來調整 OpenGL 函式 glLookAt 的視角。

另外,對於紋理對映,我暫時用一種簡化的方式來實現,即直接把幀畫面的紋理資料(RGB值)賦值到點雲的顏色中 glColor3f ,這樣的做法缺點是顯示的三維點雲是分塊、不連續的,前方的點雲塊後面是黑色空洞。接下來會繼續嘗試按正常的紋理對映方法來實現,最終實現的效果應該是類似大象帖子中提到的 Structure From Motion 軟體所實現的效果:

StructureFromMotion

  1. /************************************************************************/
  2. /*                                           OpenGL響應函式                                                 */
  3. /************************************************************************/
  4. //////////////////////////////////////////////////////////////////////////
  5. // 功能鍵(方向鍵)響應函式
  6. void special(int key, int x, int y)  
  7. {  
  8.     switch(key)  
  9.     {  
  10.     case GLUT_KEY_LEFT:  
  11.         ry-=5;  
  12.         glutPostRedisplay();  
  13.         break;  
  14.     case GLUT_KEY_RIGHT:  
  15.         ry+=5;  
  16.         glutPostRedisplay();  
  17.         break;  
  18.     case GLUT_KEY_UP:  
  19.         rx+=5;  
  20.         glutPostRedisplay();  
  21.         break;  
  22.     case GLUT_KEY_DOWN:  
  23.         rx-=5;  
  24.         glutPostRedisplay();  
  25.         break;  
  26.     }  
  27. }  
  28. //////////////////////////////////////////////////////////////////////////
  29. // 三維影象顯示響應函式
  30. void renderScene(void) {  
  31.     glClear (GL_COLOR_BUFFER_BIT);  
  32.     glLoadIdentity();// Reset the coordinate system before modifying 
  33.     gluLookAt (eyex-100, 0.0, eyez-100.0, atx-100.0, 0.0, atz-100.0, 0.0, 1.0, 0.0);    // 根據滑動塊位置變換OpenGL攝像機視角
  34.     glRotatef(ry, 0.0, 1.0, 0.0); //rotate about the z axis            // 根據鍵盤方向鍵按鍵訊息變換攝像機視角
  35.     glRotatef(rx-180, 1.0, 0.0, 0.0); //rotate about the y axis
  36.     float x,y,z;  
  37.     glPointSize(1.0);   
  38.     glBegin(GL_POINTS);//GL_POINTS
  39.     for (int i=0;i<height;i++){   
  40.         for (int j=0;j<width;j++){  
  41.             glColor3f(texture[i][j][0]/255, texture[i][j][1]/255, texture[i][j][2]/255);    // 將影象紋理賦值到點雲上
  42.             x=-imgdata[i][j][0]/scalar;        // 新增負號以獲得正確的左右上下方位
  43.             y=-imgdata[i][j][1]/scalar;   
  44.             z=imgdata[i][j][2]/scalar;   
  45.             glVertex3f(x,y,z);   
  46.         }  
  47.     }  
  48.     glEnd();  
  49.     glFlush();  
  50. }  
  51. //////////////////////////////////////////////////////////////////////////
  52. // 視窗變化影象重構響應函式
  53. void reshape (int w, int h) {  
  54.     glViewport (0, 0, (GLsizei)w, (GLsizei)h);  
  55.     glMatrixMode (GL_PROJECTION);  
  56.     glLoadIdentity ();  
  57.     gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 500.0);    // 顯示 1 - 500 距離單位(這裡是 cm)內的點雲
  58.     glMatrixMode (GL_MODELVIEW);  
  59. }  
  60. //////////////////////////////////////////////////////////////////////////
  61. // 載入三維座標資料
  62. void load3dDataToGL(IplImage* img3d){  
  63.     CvScalar s;  
  64.     //accessing the image pixels
  65. 相關推薦

    使用OpenGL顯示雙目視覺重構效果

    上一篇筆記中使用Matlab初步顯示了雙目視覺重構出的環境三維效果圖,不過並沒有加上紋理資訊。在OpenCV中文論壇裡,大象的帖子(http://www.opencv.org.cn/forum/viewtopic.php?f=1&t=8722&sid=0

    雙目視覺重建

    一、三維重建概述          三維重建主要是研究如何從得到的匹配點中計算出相機的投影矩陣(如果是外部標定的話,就是求出相機的外部引數)以及如何計算出匹配點的三維座標。         目前研究的進展與之還相差較遠。研究人員為了能夠表達三維空間資訊,目前較多地採用三維向

    雙目視覺重建框架

    玉米竭力用輕鬆具體的描述來講述雙目三維重建中的一些數學問題。希望這樣的方式讓大家以一個輕鬆的心態閱讀玉米的《計算機視覺學習筆記》雙目視覺數學架構系列部落格。這個系列部落格旨在捋順一下已標定的雙目視覺中的數學主線。數學推導是有著幾分枯燥的,但奇妙的計算機視覺世界是建立在嚴密的數學架構之上的。所以

    雙目立體視覺重建

    雙目立體視覺的整體流程包括:影象獲取、雙目標定、雙目矯正、立體匹配、三維重建。 影象獲取 雙目相機拍攝獲取 左右目影象 雙目標定 內參 外參 相機矩陣

    基於OpenGL和OpenCV的顯示

            最近想用OpenCV+OpenGL+QT實現三維顯示,但是一直都麼有弄出來,今天看了一篇部落格,感覺很不錯,拿來分享下。 簡而言之,這段程式碼是如何從disparity image獲得點雲資料(Point cloud)並利用OpenGL顯示出來。 如果想

    視覺-視覺技術-理論篇】視覺技術----雙目立體視覺,結構光等-戰略總結0

    作者冀然 摘要 結構光三維測量技術是解決非接觸三維測量問題的一個有效途徑,它彌補了傳統機器視覺以二維強度影象恢復三維景物的過程中損失了深度資訊的缺陷,可實現對三維景物的完整描述。 本文

    Windows Phone開發(19):透視效果

    end 理論知識 form 之間 3d模型 中間 第一個 一個 好的 三維效果也可以叫透視效果,所以,我幹脆叫三維透視效果。理論知識少講,直接用例開場吧,因為這個三維效果其實很簡單,比上一節中的變換更省事,不信?一起來做一做練習吧。 練習一:把對象沿Y軸旋轉45度。 默認情

    利用線結構光進行重構(測距)

    def 變量 vsc strong efi 點距 alc rational harris 利用線結構光進行三維重構(測距) 通過線激光器掃描物體,同時用攝像機對其拍照得到帶有結構光的圖片,提取結構光上的點的三維坐標,激光器掃描整個物體就可求出所有點的三維坐標實現物體表面

    轉載【重構

    版權宣告:本文為博主原創文章,可以隨意轉載。    https://blog.csdn.net/baidu_31981559/article/details/65634814 三維重建 最近在寫畢業論文,研究了下三維重建的一些東西,記錄下來,以備留存。另外有其他的問題的

    OpenCV Using Python——單目視覺重建

    import cv2 import numpy as np import glob ################################################################################ print 'criteria and object poin

    OpenCV Using Python——基於SURF特徵提取和金字塔LK光流法的單目視覺重建

    基於SURF特徵提取和金字塔LK光流法的單目視覺三維重建 1. 單目視覺三維重建問題         在前面的文章中,筆者用SIFT提取特徵後用radio測試剔除了匹配中異常的特徵點,然後根據匹配合格的特徵點計算基礎矩陣和本徵矩陣,對本徵矩陣SVD分解來估計和構造透視矩陣,

    OpenGL學習筆記(五)---地圖

    1.簡介         由於自己對WIN API不熟悉,所以把Nehe例程改成了“純”C++實現,當然,windows下程式設計還是用到了<windows.h>裡定義的一些巨集、結構體.....         NeHe教程10是用一張.bmp點陣圖實現了一個

    OpenGL(九) 混色和深度快取設定

    顏色的混合在現實世界中非常常見,例如隔著有色玻璃觀看物體,此時在觀察者嚴重呈現出來物體的顏色就是玻璃的顏色和物體的顏色的混合。 OpenGL在RGBA顏色模式下使用函式glenable(GL_BLEND)開啟混色功能,使用glDisable(GL_BLEDN)關閉混色功能。

    心臟重構的調研報告

    最近導師讓做一個關於心臟的三維重構報告,查閱了很多的資料,這一塊感覺還是比較冷門的,所以更新一下,希望能夠幫助後來的童鞋~~~1.調研背景  1.1背景介紹        近年來,CT、CR、DR、MRI、 US、PET、SPECT 等多種成像技術開始逐漸成熟並在醫學疾病診斷

    OpenGL(五) 變換之模型檢視矩陣

    計算機三維圖形學中,一個基本的任務是如何描述三維空間中一個物體位置的變化,也就是如何 描述物體的運動。通常情況下,物體位置的變化包含三個基本的變化:平移、旋轉和縮放,物體的運動也可以用這三個基本的運動

    PCL系列——重構之貪婪三角投影演算法

    長期招聘計算機視覺/深度學習等方向的工程師或實習生。感興趣的話,請傳送郵件,可以內推。 PCL系列 說明 通過本教程,我們將會學會: 如果通過貪婪三角投影演算法進行三維點雲重構。 程式支援兩種檔案格式:*.pcd和*.ply。 程

    Android OpenGL ES (二) 繪製/空間座標系

     * 此檔案是關於3D座標軸的繪製,用jiasu.java和jiasu.xml實現了使用者介面  * 關於3D處理的所有程式都在此檔案中  *zjk 2014/03/04  */ public class Jiasudu implements Renderer {float x=-0.5f,y=-0.5f,z

    雙目+rtabmap_ros建圖

    挑選合適版本安裝https://github.com/introlab/rtabmap_ros#installation     RTAB-Map is released as binaries in the ROS distribution.     Lunar    

    Android OpenGL ES(六)----進入在程式碼中建立投影矩陣和旋轉矩陣

    我們現在準備好在程式碼中新增透視投影了。Android的Matrix類為它準備了兩個方法------frustumM()和perspectiveM()。不幸的是,frustumM()的個缺陷,它會影響某些型別的投影,而perspectiveM()只是從Android的ICS

    一段很棒的利用html5-canvas及javascript產生星空效果的程式碼!

    從網上搜集到的一段利用純html5-canvas以及javascript生成三維星空效果的程式碼。程式碼的核心部分是“<script></script>”標籤中包含的外部javascript程式碼-html5_3d_animation.js,即本文的