我的Kinect型号:PrimeSense Carmine
使用Openni2.0
这次比较粗糙,就是想将摄像头采集的深度信息转化为现实世界的三维坐标,然后用Opengl画出来。
这里没有降噪、取样,所以也称不上是“点云”
他是Openni1.0做的,代码写的也比较规整,我就比较随意了,适合像我一样的新手理解
[cpp] view plaincopy
#include<gl/glut.h>
#include <iostream>
#include <vector>
#include <OpenNI.h>
#include "OniSampleUtilities.h"
#define SAMPLE_READ_WAIT_TIMEOUT 200 //2000ms
using namespace openni;
using namespace std;
typedef struct data
{
float x;
float y;
float z;
}data;
VideoStream depth;
VideoFrameRef frame;
int width;
int height;
void OpenGL_init(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color: white
glShadeModel(GL_FLAT);
glClear(GL_COLOR_BUFFER_BIT);
}
void display()
{
vector<data> point;
data mydata;
float x=0.0,y=0.0,z=0.0,xx=0.0;
float i,j;
//读取一帧
int changedStreamDummy;
VideoStream* pStream = &depth;
OpenNI::waitForAnyStream(&pStream, 1, &changedStreamDummy, SAMPLE_READ_WAIT_TIMEOUT);
depth.readFrame(&frame);
width = frame.getWidth();
height = frame.getHeight();
DepthPixel *pDepth = (DepthPixel*)frame.getData();
for(i=0;i<frame.getHeight();i++)
{
for(j=0;j<frame.getWidth();j++)
{
int k = i;
int m = j;
xx = pDepth[k*frame.getWidth()+m];
CoordinateConverter::convertDepthToWorld (depth,i,j,xx,&x,&y,&z);
mydata.x=x*0.001;
mydata.y=y*0.001;
mydata.z=z*0.001;
point.push_back(mydata);
//cout<<xx<<endl;
}
}
glColor3f(1.0f, 1.0f, 1.0f);
glPointSize(0.1f);
glBegin(GL_POINTS);
if (point.size()!=0)
{
glBegin(GL_POINTS);
for (vector<data>::iterator iter = point.begin();iter!=point.end();iter++)
{
glVertex3f(iter->x,iter->y,iter->z);
}
}
glEnd();
glFlush();
glutSwapBuffers();
}
void OpenGL_changeSize(int w, int h)
{
glViewport(0, 0, GLsizei(w), GLsizei(h));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// if (w <= h) // 正交投影
// glOrtho(-2.0, 2.0, -2.0*(GLfloat)h/(GLfloat)w, 2.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
// else
// glOrtho(-2.0*(GLfloat)w/(GLfloat)h, 2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0, -10.0, 10.0);
gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.1f, 50.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f);
}
void OpenGL_Idel()
{
display(); // 刷新显示
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char **argv)
{
Status rc = OpenNI::initialize();
vector<data> point;
Device device;
rc = device.open(ANY_DEVICE);
if (device.getSensorInfo(SENSOR_DEPTH) != NULL)
{
rc = depth.create(device, SENSOR_DEPTH);
}
rc = depth.start();
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800, 600);
glutCreateWindow("first blood");
OpenGL_init();
glutDisplayFunc(&display);
glutIdleFunc(OpenGL_Idel);
glutMainLoop();
return 0;
}
OPENNI2.0 sample里带的图:
背景是书架+我的手
下面这幅是还原三维世界:
下次将学习PCL的东西,争取给出以下效果:
使用Openni2.0
这次比较粗糙,就是想将摄像头采集的深度信息转化为现实世界的三维坐标,然后用Opengl画出来。
这里没有降噪、取样,所以也称不上是“点云”
他是Openni1.0做的,代码写的也比较规整,我就比较随意了,适合像我一样的新手理解
[cpp] view plaincopy
#include<gl/glut.h>
#include <iostream>
#include <vector>
#include <OpenNI.h>
#include "OniSampleUtilities.h"
#define SAMPLE_READ_WAIT_TIMEOUT 200 //2000ms
using namespace openni;
using namespace std;
typedef struct data
{
float x;
float y;
float z;
}data;
VideoStream depth;
VideoFrameRef frame;
int width;
int height;
void OpenGL_init(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // background color: white
glShadeModel(GL_FLAT);
glClear(GL_COLOR_BUFFER_BIT);
}
void display()
{
vector<data> point;
data mydata;
float x=0.0,y=0.0,z=0.0,xx=0.0;
float i,j;
//读取一帧
int changedStreamDummy;
VideoStream* pStream = &depth;
OpenNI::waitForAnyStream(&pStream, 1, &changedStreamDummy, SAMPLE_READ_WAIT_TIMEOUT);
depth.readFrame(&frame);
width = frame.getWidth();
height = frame.getHeight();
DepthPixel *pDepth = (DepthPixel*)frame.getData();
for(i=0;i<frame.getHeight();i++)
{
for(j=0;j<frame.getWidth();j++)
{
int k = i;
int m = j;
xx = pDepth[k*frame.getWidth()+m];
CoordinateConverter::convertDepthToWorld (depth,i,j,xx,&x,&y,&z);
mydata.x=x*0.001;
mydata.y=y*0.001;
mydata.z=z*0.001;
point.push_back(mydata);
//cout<<xx<<endl;
}
}
glColor3f(1.0f, 1.0f, 1.0f);
glPointSize(0.1f);
glBegin(GL_POINTS);
if (point.size()!=0)
{
glBegin(GL_POINTS);
for (vector<data>::iterator iter = point.begin();iter!=point.end();iter++)
{
glVertex3f(iter->x,iter->y,iter->z);
}
}
glEnd();
glFlush();
glutSwapBuffers();
}
void OpenGL_changeSize(int w, int h)
{
glViewport(0, 0, GLsizei(w), GLsizei(h));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// if (w <= h) // 正交投影
// glOrtho(-2.0, 2.0, -2.0*(GLfloat)h/(GLfloat)w, 2.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
// else
// glOrtho(-2.0*(GLfloat)w/(GLfloat)h, 2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0, -10.0, 10.0);
gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.1f, 50.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.0f);
}
void OpenGL_Idel()
{
display(); // 刷新显示
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char **argv)
{
Status rc = OpenNI::initialize();
vector<data> point;
Device device;
rc = device.open(ANY_DEVICE);
if (device.getSensorInfo(SENSOR_DEPTH) != NULL)
{
rc = depth.create(device, SENSOR_DEPTH);
}
rc = depth.start();
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800, 600);
glutCreateWindow("first blood");
OpenGL_init();
glutDisplayFunc(&display);
glutIdleFunc(OpenGL_Idel);
glutMainLoop();
return 0;
}
OPENNI2.0 sample里带的图:
背景是书架+我的手
下面这幅是还原三维世界:
下次将学习PCL的东西,争取给出以下效果: