基于OpenGL和OpenCV的三维显示
最近想用OpenCV+OpenGL+QT实现三维显示,但是一直都么有弄出来,今天看了一篇博客,感觉很不错,拿来分享下。
简而言之,这段代码是如何从disparity image获得点云数据(Point cloud)并利用OpenGL显示出来。 如果想使用代码,请确认OpenGL和OpenCV都安装在电脑中。我使用的是Visual Studio 2008...(关于如何安装OPENGL 请参考http://techhouse.brown.edu/~dmorris/cs148_summer_2005/handouts/OpenGL-Install-Guide.pdf)
////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 coordinatesvoid renderScene(void) {glClear (GL_COLOR_BUFFER_BIT);glLoadIdentity();// Reset the coordinate system before modifyinggluLookAt (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 axisglRotatef(-180, 0.0, 0.0, 1.0); //rotate about the z axisglRotatef(-180, 0.0, 1.0, 0.0); //rotate about the y axisfloat imageCenterX=w*.5;float imageCenterY=h*.5;float x,y,z;glPointSize(1.0);glBegin(GL_POINTS);//GL_POINTSfor (int i=0;i<h;i++){for (int j=0;j<w;j++){// color interpolationglColor3f(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 pixelsfor (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 oneif (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;}
在此基础上,我又综合了一小段代码,随着鼠标移动,可以从多个视角观看生成的三维点云图(VS中还要加上预编译头):)
#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.1415926bool 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 modifyinggluLookAt (0.0, 0.0, 7.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0);//to invert the imageglRotatef(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_POINTSfor (int i=0;i<h;i++){for (int j=0;j<w;j++){// color interpolationglColor3f(1-imgdata[i][j]/255, imgdata[i][j]/255, imgdata[i][j]/255);//red,green,bluex=((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 viewpointglMatrixMode (GL_PROJECTION);//specify which matrix is the current matrixglLoadIdentity ();//replace the current matrix with the identity matrixgluPerspective (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 pixelsfor (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 oneif (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 libraryglutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);//sets the initial display modeglutInitWindowPosition(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;}
赞 (0)
