OpenGL将二维图形显示为三维点云图

全文参考:http://blog.csdn.net/sky_freebird/article/details/6695059


运用OpenGL实现二维图像的三维点云图显示。


#include 
#include 
#include 
#include 
#include 
//#include 
//#include 
#include 
using namespace std;

float imgdata[480][640];	//注意维度,第一维表示高度,第二维表示宽度
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);
	gluLookAt (0.0, 0.0, 7.0, -0.5, 0.5, 0.0, 0.0, 1.0, 0.0);
	//该函数定义一个视图矩阵,并与当前矩阵相乘。
	//第一组eyex, eyey,eyez 相机(观察者眼睛)在世界坐标的位置
	//第二组centerx,centery,centerz 相机镜头对准的物体在世界坐标的位置(观察者观察的方向)
	//第三组upx,upy,upz 相机向上的方向在世界坐标中的方向
	//http://www.cnblogs.com/chengmin/archive/2011/09/12/2174004.html

	//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;iwidth;
	h=imgGrey->height;

	displayDisparity(imgGrey);
	cvNamedWindow("3D disparity image", CV_WINDOW_AUTOSIZE );
	cvShowImage( "3D disparity image", imgGrey );

	
	//------------------OpenGL-------------------------
	glutInit(&argc, argv);//initialize the GLUT library
	glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);	//设置初始化显示模式
	//GLUT_RGBA颜色模式;GLUT_SINGLE单缓存模式,GLUT_DEPTH深度缓存模式
	//单缓冲,实际上就是将所有的绘图指令在窗口上执行,就是直接在窗口上绘图,这样的绘图效率是比较慢的,如果使用单缓冲,而电脑比较慢,你会看到屏幕的闪烁。
	//双缓冲,实际上的绘图指令是在一个缓冲区完成,这里的绘图非常的快,在绘图指令完成之后,再通过交换指令把完成的图形立即显示在屏幕上,这就避免了出现绘图的不完整,同时效率很高。
	//一般用OpenGL绘图都是用双缓冲,单缓冲一般只用于显示单独的一副非动态的图像。
	//深度缓冲:http://zh.wikipedia.org/wiki/%E6%B7%B1%E5%BA%A6%E7%BC%93%E5%86%B2
	glutInitWindowPosition(600,200);	//设置初始化窗口位置
	glutInitWindowSize(640,480);	//设置初始化窗口大小
	glutCreateWindow("3D disparity image");	//创建窗口
	glutDisplayFunc(renderScene);	
	//glutDisplayFunc函数用于注册一个绘图函数, 这样操作系统在必要时刻就会对窗体进行重新绘制操作。类似于windows程序设计中处理WM_PAINT消息。

	glutReshapeFunc (reshape);	
	//glutReshapeFunc了解:http://zhidao.baidu.com/link?url=K_GPs7mXbe6H1M_OA-YibtC7-1GNqv8efOKC_jMDxiK7kRSHt_zBzH5eIQaao0tK9RQGegwX2r_CH2N5nSsufK
	glutMouseFunc(mouse);
	glutMotionFunc(motion);
	glutSpecialFunc(special);

	
	glutMainLoop();	//glutMainLoop进入GLUT事件处理循环,让所有的与“事件”有关的函数调用无限循环。
	//glutMainLoopEvent();
	

	//cvWaitKey(0);
	//release opencv stuff.
	//system("pause");
	cvReleaseImage(&imgGrey);
	cvDestroyWindow("3D disparity image");

	return 0;
}

要实现二维图像的三维显示,需要把相关的地方改一下。

RGB图像,需要将数组定义为3维数组。

float imgdata[480][640][3];

相关函数需要改一下:

void displayDisparity(IplImage* disparity){
	//double xyscale=100;
	int j=0;
	int i=0;
	CvScalar s;

	//accessing the image pixels
	for (i=0;i

glColor3f(imgdata[i][j][0]/255, imgdata[i][j][1]/255, imgdata[i][j][2]/255);//red,green,blue

glBegin(GL_POINTS);//GL_POINTS
	for (int i=0;i如果有扫描到的物体表面高度信息,可以在此处赋高度信息;此处以blue分量作为z坐标
			/*z=(imgdata[i][j])/scalar;*/

			glVertex3f(x,y,z);	//坐标视角函数
		}
	}
	glEnd();
OpenGL将二维图形显示为三维点云图_第1张图片

下图旋转了一定角度,可以看出blue分量值越大,Z坐标值越大,blue的位置越靠前(右手坐标系,Z正方向为从电脑向人的指向)。

OpenGL将二维图形显示为三维点云图_第2张图片

你可能感兴趣的:(视频图像处理)