基於OpenGL和OpenCV的三維顯示
阿新 • • 發佈:2019-01-10
最近想用OpenCV+OpenGL+QT實現三維顯示,但是一直都麼有弄出來,今天看了一篇部落格,感覺很不錯,拿來分享下。
簡而言之,這段程式碼是如何從disparity image獲得點雲資料(Point cloud)並利用OpenGL顯示出來。 如果想使用程式碼,請確認OpenGL和OpenCV都安裝在電腦中。我使用的是Visual Studio 2008...(關於如何安裝OPENGL 請參
在此基礎上,我又綜合了一小段程式碼,隨著滑鼠移動,可以從多個視角觀看生成的三維點雲圖(VS中還要加上預編譯頭):)// //Huang,Haiqiao coded on Dec.2009 #include "stdafx.h" #include <iostream> #include <stdlib.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> #include <math.h> #include <GL/glut.h> using namespace std; float imgdata[500][500]; int w=0; int h=0; float scalar=50;//scalar of converting pixel color to float coordinates void renderScene(void) { glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity();// Reset the coordinate system before modifying gluLookAt (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //glRotatef(-30, 0.0, 1.0, 0.0); //rotate about the x axis glRotatef(-180, 0.0, 0.0, 1.0); //rotate about the z axis glRotatef(-180, 0.0, 1.0, 0.0); //rotate about the y axis float imageCenterX=w*.5; float imageCenterY=h*.5; float x,y,z; glPointSize(1.0); glBegin(GL_POINTS);//GL_POINTS for (int i=0;i<h;i++){ for (int j=0;j<w;j++){ // color interpolation glColor3f(1-imgdata[i][j]/255, imgdata[i][j]/255, imgdata[i][j]/255); x=((float)j-imageCenterX)/scalar; y=((float)i-imageCenterY)/scalar; z=imgdata[i][j]/scalar; glVertex3f(x,y,z); } } glEnd(); glFlush(); } void reshape (int w, int h) { glViewport (0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); glMatrixMode (GL_MODELVIEW); } void displayDisparity(IplImage* disparity){ double xyscale=100; int j=0; int i=0; CvScalar s; //accessing the image pixels for (i=0;i<h;i++){ for (j=0;j<w;j++){ s=cvGet2D(disparity,i,j); imgdata[i][j]=s.val[0];//for disparity is a grey image. } } } int main(int argc, char *argv[]) { cout << "OpenCV and OpenGL working together!"<<endl; char* filename="D:\\OpenCV_stuff\\SampleImages\\tsuDisparity.bmp"; IplImage* imgGrey = cvLoadImage(filename,0); //read image as a grey one if (imgGrey==NULL){ cout << "No valid image input."<<endl; char c=getchar(); return 1; } w=imgGrey->width; h=imgGrey->height; displayDisparity(imgGrey); cvNamedWindow("original", CV_WINDOW_AUTOSIZE ); cvShowImage( "original", imgGrey ); //------------------OpenGL------------------------- glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA); glutInitWindowPosition(100,100); glutInitWindowSize(500,500); glutCreateWindow("3D disparity image"); glutDisplayFunc(renderScene); glutReshapeFunc (reshape); glutMainLoop(); cvWaitKey(0); //release opencv stuff. cvReleaseImage(&imgGrey); cvDestroyWindow("Original"); return 0; }
#include <iostream> #include <stdlib.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> #include <math.h> #include <gl/glut.h> using namespace std; float imgdata[500][500]; int w=0; int h=0; float scalar=50;//scalar of converting pixel color to float coordinates #define pi 3.1415926 bool mouseisdown=false; bool loopr=false; int mx,my; int ry=10; int rx=10; void timer(int p) { ry-=5; //marks the current window as needing to be redisplayed. glutPostRedisplay(); if (loopr) glutTimerFunc(200,timer,0); } void mouse(int button, int state, int x, int y) { if(button == GLUT_LEFT_BUTTON) { if(state == GLUT_DOWN) { mouseisdown=true; loopr=false; } else { mouseisdown=false; } } if (button== GLUT_RIGHT_BUTTON) if(state == GLUT_DOWN) { loopr=true; glutTimerFunc(200,timer,0); } } void motion(int x, int y) { if(mouseisdown==true) { ry+=x-mx; rx+=y-my; mx=x; my=y; glutPostRedisplay(); } } void special(int key, int x, int y) { switch(key) { case GLUT_KEY_LEFT: ry-=5; glutPostRedisplay(); break; case GLUT_KEY_RIGHT: ry+=5; glutPostRedisplay(); break; case GLUT_KEY_UP: rx+=5; glutPostRedisplay(); break; case GLUT_KEY_DOWN: rx-=5; glutPostRedisplay(); break; } } void renderScene(void) { glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity();// Reset the coordinate system before modifying gluLookAt (0.0, 0.0, 7.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0); //to invert the image glRotatef(ry,0,1,0); glRotatef(rx-180,1,0,0); float imageCenterX=w*.5; float imageCenterY=h*.5; float x,y,z; glPointSize(1.0); glBegin(GL_POINTS);//GL_POINTS for (int i=0;i<h;i++){ for (int j=0;j<w;j++){ // color interpolation glColor3f(1-imgdata[i][j]/255, imgdata[i][j]/255, imgdata[i][j]/255);//red,green,blue x=((float)j-imageCenterX)/scalar; y=((float)i-imageCenterY)/scalar; z=(255-imgdata[i][j])/scalar; glVertex3f(x,y,z); } } glEnd(); glFlush(); } void reshape (int w, int h) { glViewport (0, 0, (GLsizei)w, (GLsizei)h);//set viewpoint glMatrixMode (GL_PROJECTION);//specify which matrix is the current matrix glLoadIdentity ();//replace the current matrix with the identity matrix gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); glMatrixMode (GL_MODELVIEW); } void displayDisparity(IplImage* disparity){ //double xyscale=100; int j=0; int i=0; CvScalar s; //accessing the image pixels for (i=0;i<h;i++){ for (j=0;j<w;j++){ s=cvGet2D(disparity,i,j); imgdata[i][j]=s.val[0];//for disparity is a grey image. //cout << imgdata[i][j]<<endl; } } } int main(int argc, char *argv[]) { cout << "OpenCV and OpenGL works together!"<<endl; char* filename=argv[1]; IplImage* imgGrey = cvLoadImage(filename,0); //read image as a grey one if (imgGrey==NULL){ cout << "No valid image input."<<endl; return 1; } w=imgGrey->width; h=imgGrey->height; displayDisparity(imgGrey); cvNamedWindow("original", CV_WINDOW_AUTOSIZE ); cvShowImage( "original", imgGrey ); //------------------OpenGL------------------------- glutInit(&argc, argv);//initialize the GLUT library glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);//sets the initial display mode glutInitWindowPosition(100,100); glutInitWindowSize(500,500); glutCreateWindow("3D disparity image"); glutDisplayFunc(renderScene); glutReshapeFunc (reshape); glutMouseFunc(mouse); glutMotionFunc(motion); glutSpecialFunc(special); glutMainLoop(); cvWaitKey(0); //release opencv stuff. cvReleaseImage(&imgGrey); cvDestroyWindow("Original"); return 0; }