基于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 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; 
}



在此基础上,我又综合了一小段代码,随着鼠标移动,可以从多个视角观看生成的三维点云图(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.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;
    }



  • 4
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值