基于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)

  1. //
  2. //Huang,Haiqiao coded on Dec.2009
  3. #include 'stdafx.h'
  4. #include <iostream>
  5. #include <stdlib.h>
  6. #include <cv.h>
  7. #include <cxcore.h>
  8. #include <highgui.h>
  9. #include <math.h>
  10. #include <GL/glut.h>
  11. using namespace std;
  12. float imgdata[500][500];
  13. int w=0;
  14. int h=0;
  15. float scalar=50;//scalar of converting pixel color to float coordinates
  16. void renderScene(void) {
  17. glClear (GL_COLOR_BUFFER_BIT);
  18. glLoadIdentity();// Reset the coordinate system before modifying
  19. gluLookAt (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
  20. //glRotatef(-30, 0.0, 1.0, 0.0); //rotate about the x axis
  21. glRotatef(-180, 0.0, 0.0, 1.0); //rotate about the z axis
  22. glRotatef(-180, 0.0, 1.0, 0.0); //rotate about the y axis
  23. float imageCenterX=w*.5;
  24. float imageCenterY=h*.5;
  25. float x,y,z;
  26. glPointSize(1.0);
  27. glBegin(GL_POINTS);//GL_POINTS
  28. for (int i=0;i<h;i++){
  29. for (int j=0;j<w;j++){
  30. // color interpolation
  31. glColor3f(1-imgdata[i][j]/255, imgdata[i][j]/255, imgdata[i][j]/255);
  32. x=((float)j-imageCenterX)/scalar;
  33. y=((float)i-imageCenterY)/scalar;
  34. z=imgdata[i][j]/scalar;
  35. glVertex3f(x,y,z);
  36. }
  37. }
  38. glEnd();
  39. glFlush();
  40. }
  41. void reshape (int w, int h) {
  42. glViewport (0, 0, (GLsizei)w, (GLsizei)h);
  43. glMatrixMode (GL_PROJECTION);
  44. glLoadIdentity ();
  45. gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
  46. glMatrixMode (GL_MODELVIEW);
  47. }
  48. void displayDisparity(IplImage* disparity){
  49. double xyscale=100;
  50. int j=0;
  51. int i=0;
  52. CvScalar s;
  53. //accessing the image pixels
  54. for (i=0;i<h;i++){
  55. for (j=0;j<w;j++){
  56. s=cvGet2D(disparity,i,j);
  57. imgdata[i][j]=s.val[0];//for disparity is a grey image.
  58. }
  59. }
  60. }
  61. int main(int argc, char *argv[])
  62. {
  63. cout << 'OpenCV and OpenGL working together!'<<endl;
  64. char* filename='D:\\OpenCV_stuff\\SampleImages\\tsuDisparity.bmp';
  65. IplImage* imgGrey = cvLoadImage(filename,0); //read image as a grey one
  66. if (imgGrey==NULL){
  67. cout << 'No valid image input.'<<endl;
  68. char c=getchar();
  69. return 1;
  70. }
  71. w=imgGrey->width;
  72. h=imgGrey->height;
  73. displayDisparity(imgGrey);
  74. cvNamedWindow('original', CV_WINDOW_AUTOSIZE );
  75. cvShowImage( 'original', imgGrey );
  76. //------------------OpenGL-------------------------
  77. glutInit(&argc, argv);
  78. glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
  79. glutInitWindowPosition(100,100);
  80. glutInitWindowSize(500,500);
  81. glutCreateWindow('3D disparity image');
  82. glutDisplayFunc(renderScene);
  83. glutReshapeFunc (reshape);
  84. glutMainLoop();
  85. cvWaitKey(0);
  86. //release opencv stuff.
  87. cvReleaseImage(&imgGrey);
  88. cvDestroyWindow('Original');
  89. return 0;
  90. }

在此基础上,我又综合了一小段代码,随着鼠标移动,可以从多个视角观看生成的三维点云图(VS中还要加上预编译头):)

  1. #include <iostream>
  2. #include <stdlib.h>
  3. #include <cv.h>
  4. #include <cxcore.h>
  5. #include <highgui.h>
  6. #include <math.h>
  7. #include <gl/glut.h>
  8. using namespace std;
  9. float imgdata[500][500];
  10. int w=0;
  11. int h=0;
  12. float scalar=50;//scalar of converting pixel color to float coordinates
  13. #define pi 3.1415926
  14. bool mouseisdown=false;
  15. bool loopr=false;
  16. int mx,my;
  17. int ry=10;
  18. int rx=10;
  19. void timer(int p)
  20. {
  21. ry-=5;
  22. //marks the current window as needing to be redisplayed.
  23. glutPostRedisplay();
  24. if (loopr)
  25. glutTimerFunc(200,timer,0);
  26. }
  27. void mouse(int button, int state, int x, int y)
  28. {
  29. if(button == GLUT_LEFT_BUTTON)
  30. {
  31. if(state == GLUT_DOWN)
  32. {
  33. mouseisdown=true;
  34. loopr=false;
  35. }
  36. else
  37. {
  38. mouseisdown=false;
  39. }
  40. }
  41. if (button== GLUT_RIGHT_BUTTON)
  42. if(state == GLUT_DOWN)
  43. {
  44. loopr=true; glutTimerFunc(200,timer,0);
  45. }
  46. }
  47. void motion(int x, int y)
  48. {
  49. if(mouseisdown==true)
  50. {
  51. ry+=x-mx;
  52. rx+=y-my;
  53. mx=x;
  54. my=y;
  55. glutPostRedisplay();
  56. }
  57. }
  58. void special(int key, int x, int y)
  59. {
  60. switch(key)
  61. {
  62. case GLUT_KEY_LEFT:
  63. ry-=5;
  64. glutPostRedisplay();
  65. break;
  66. case GLUT_KEY_RIGHT:
  67. ry+=5;
  68. glutPostRedisplay();
  69. break;
  70. case GLUT_KEY_UP:
  71. rx+=5;
  72. glutPostRedisplay();
  73. break;
  74. case GLUT_KEY_DOWN:
  75. rx-=5;
  76. glutPostRedisplay();
  77. break;
  78. }
  79. }
  80. void renderScene(void) {
  81. glClear (GL_COLOR_BUFFER_BIT);
  82. glLoadIdentity();// Reset the coordinate system before modifying
  83. gluLookAt (0.0, 0.0, 7.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0);
  84. //to invert the image
  85. glRotatef(ry,0,1,0);
  86. glRotatef(rx-180,1,0,0);
  87. float imageCenterX=w*.5;
  88. float imageCenterY=h*.5;
  89. float x,y,z;
  90. glPointSize(1.0);
  91. glBegin(GL_POINTS);//GL_POINTS
  92. for (int i=0;i<h;i++){
  93. for (int j=0;j<w;j++){
  94. // color interpolation
  95. glColor3f(1-imgdata[i][j]/255, imgdata[i][j]/255, imgdata[i][j]/255);//red,green,blue
  96. x=((float)j-imageCenterX)/scalar;
  97. y=((float)i-imageCenterY)/scalar;
  98. z=(255-imgdata[i][j])/scalar;
  99. glVertex3f(x,y,z);
  100. }
  101. }
  102. glEnd();
  103. glFlush();
  104. }
  105. void reshape (int w, int h) {
  106. glViewport (0, 0, (GLsizei)w, (GLsizei)h);//set viewpoint
  107. glMatrixMode (GL_PROJECTION);//specify which matrix is the current matrix
  108. glLoadIdentity ();//replace the current matrix with the identity matrix
  109. gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
  110. glMatrixMode (GL_MODELVIEW);
  111. }
  112. void displayDisparity(IplImage* disparity){
  113. //double xyscale=100;
  114. int j=0;
  115. int i=0;
  116. CvScalar s;
  117. //accessing the image pixels
  118. for (i=0;i<h;i++){
  119. for (j=0;j<w;j++){
  120. s=cvGet2D(disparity,i,j);
  121. imgdata[i][j]=s.val[0];//for disparity is a grey image.
  122. //cout << imgdata[i][j]<<endl;
  123. }
  124. }
  125. }
  126. int main(int argc, char *argv[])
  127. {
  128. cout << 'OpenCV and OpenGL works together!'<<endl;
  129. char* filename=argv[1];
  130. IplImage* imgGrey = cvLoadImage(filename,0); //read image as a grey one
  131. if (imgGrey==NULL){
  132. cout << 'No valid image input.'<<endl;
  133. return 1;
  134. }
  135. w=imgGrey->width;
  136. h=imgGrey->height;
  137. displayDisparity(imgGrey);
  138. cvNamedWindow('original', CV_WINDOW_AUTOSIZE );
  139. cvShowImage( 'original', imgGrey );
  140. //------------------OpenGL-------------------------
  141. glutInit(&argc, argv);//initialize the GLUT library
  142. glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);//sets the initial display mode
  143. glutInitWindowPosition(100,100);
  144. glutInitWindowSize(500,500);
  145. glutCreateWindow('3D disparity image');
  146. glutDisplayFunc(renderScene);
  147. glutReshapeFunc (reshape);
  148. glutMouseFunc(mouse);
  149. glutMotionFunc(motion);
  150. glutSpecialFunc(special);
  151. glutMainLoop();
  152. cvWaitKey(0);
  153. //release opencv stuff.
  154. cvReleaseImage(&imgGrey);
  155. cvDestroyWindow('Original');
  156. return 0;
  157. }

(0)

相关推荐