Kinectè²·ã£ããï¼
ãã¼ããã£ããTwitterã使ãããã«ãªã£ã¦ããã°ã®æ´æ°ãæ¢ã¾ãã¾ãããä»ã®äººããããã£ã¦ããã®ã§ããããããããªãã§ããããã¨è¨ã訳ã§ã@kamiyan ä¸ã§ä¼ãã¾ããããã
ãããããã°ã«æ¸ããªããã£ã¦ã®ã¯Kinectã§ããï¼ããããééã¨ããMakeééã¨ããé»åå·¥ä½ééã«ã¯å¿
é ã§ããï¼ï¼
Kinectã®PCç¨ãã©ã¤ãããªã¼ãã³ã½ã¼ã¹ã§åºãã¨èãã¦ã12æã®5æ¥ã«è²·ã£ã¦ãã¾ããããã¢ãããã¨ããã·ã§13,000åã»ã©ã ã£ãã§ããããï¼ãã¡ããXbox360ã¯æã£ã¦ããªããããã¶ãè²·ããªããã©ã
注æäºé
ã¯ãXbox360+Kinectã»ããã売ã£ã¦ãããããã£ã¡ã ã¨PCã§ã¤ãªãã¨ãã«å¿
è¦ãªACã¢ããã¿ã¼ãå
¥ã£ã¦ããªããããã®ã§ãKinectã®ã¿ã®æ¹ãè²·ããã¨ãããã¡ãã£ã¨è©³ãã説æããã¨ãKinectã¯ãä»å±ã®ACã¢ããã¿ã¼ã®å®æ ¼ãã¿ãã¨ã12V-1.08Aã®é»æºãè¦ã模æ§ãXbox360+Kinectã»ããã®Kinectã¯USBãã¹ãã¯ã¼ã®ã¿ã§åããããããæ®é USBãã¹ãã¯ã¼ã¯5Vãªã®ã§ã5Vã®ãã¹ãã¯ã¼ã§åãé»åãå¾ããã¨æã£ãã2.5Aãããé»æµãåãåºããªãã¨ãããªããæ®éPCã®USBãã¼ãã¯ã500mAã¨ã1Aããããé度ã§ã¯ãªãããªï¼è©³ãããªããã©ï¼ããªã®ã§ãPCã§ã¤ãªãå ´åã¯ACé»æºãå¿
è¦ãã§ãXbox360+Kinectã»ããã®Xbox360ã¯æ°ããXboxããããã¹ãã¯ã¼ã®é»åã大ããã®ã§ããããããã¦æ§åã®Xbox360ã®äººã¯ãKinectåä½ãè²·ã£ã¦ãï¼ï¼åä½çã¯ãACã¢ããã¿ä»ãï¼ã¨ãã訳ã ã
ã§ãè²·ã£ã¦ãã¦åæ¥ã»ã©ã§ãã¡ãã£ã¨ã³ã¼ããæ¸ãã¾ããããã®ã¨ãã®ã¡ã¢ã
ï¼2010/12/5ï¼
- Kinectãã©ã¤ãã§æ¤ç´¢ãã¦OpenKinect for Windows(LibUSB)Driverãå ¥ãã http://imagingsolution.blog107.fc2.com/blog-entry-269.html#Windows7
- Kinect-Demoãåãã確èª
- Kinect.slnãéãã¦ãReleaseã¨Debugã§ãã«ã
- VC++ã§æ°è¦ã«ããã¸ã§ã¯ã KinectTest.sln ãä½æã
- ããããã£ã§ãªã³ã«ã¼ï¼è¿½å ã®ã©ã¤ãã©ãªã®ãã£ã¬ã¯ããªã§ ã\workspace\Kinect-v16\Debug;ãªã©è¿½å
- ãªã³ã«ã¼ï¼å ¥åï¼è¿½å ã®ä¾åãã¡ã¤ã«ã§Kinect.libã追å
- C/C++ï¼è¿½å ã®ã¤ã³ã¯ã«ã¼ããã£ã¬ã¯ããªã§ã\Kinect-v16;追å
- KinectTest.cppã®ä¸èº«ãKinect-MinimalSample.cppã®ä¸èº«ã«ãã¦ã³ã³ãã¤ã«ï¼å®è¡
- glut-3.7.6-binãã¤ã³ã¹ãã¼ã«ãã
- ããã¸ã§ã¯ãã®ããããã£ãC/C++ï¼è¿½å ã®ã¤ã³ã¯ã«ã¼ããã£ã¬ã¯ããªã« ã\Kinect-v16\glut-3.7.6-bin; ã追å
- ãªã³ã«ï¼å ¨è¬ï¼è¿½å ã®ã©ã¤ãã©ãªãã£ã¬ã¯ããªã«ã\Kinect-v16\glut-3.7.6-bin; ã追å
- glutã®ãµã³ãã«ãèªã http://www.opengl.org/resources/code/samples/glut_examples/examples/examples.html
ã£ã¦æãã§ãã
ã¾ãã¯ãèªåãããªã´ã³åãã¦ã¿ãããï¼
ä¸å³ãæåã®ãã¼ã¸ã§ã³ãããªã´ã³ã¨ããªã´ã³ã®ééãå¤ãã
ä¸å³ãééãæ¸ãããã¤ãããå·¦æã¨é¡ã®éãã¬ã¤ã³ãã¼ã
ä¸å³ãééãæ¸ã£ãã
ä¸å³ãDepthãã¿ã¦å£ãé¤å»ã
Kinectã¯RGBã¨Depthã®4è¦ç´ ãã640x480ãã¯ã»ã«åæ¥ããããã¦ä¸è¨ã¯ã1ãã¯ã»ã«ã2ã¤ã®ä¸è§å½¢ã§æç»ãã¦ããã®ã§ã61ä¸ããªã´ã³ã61ä¸ããªã´ã³ããã£ããåãã®ã¯ãå 3Dééã¨ãã¦ææ ¨æ·±ããä¹ ãã¶ãã«OpenGL使ã£ããã18å¹´åã«ä½¿ã£ãã¬ãã«ããç¥èãå¤ãã£ã¦ããªã辺ããæ²ããï¼è¦ç¬ï¼ã
Kinectã®ä»çµã¿
Kinectã¯ããªãã§3次å
ã¹ãã£ã³ãã§ãã¦ããã®ãã
ã¹ãã¬ãªãã¸ã§ã³ã ã¨2ã¤ã®ã«ã¡ã©ã§æ®å½±ãã¦ãç¹å¾´ç¹ãæ½åºãã¦ãç¹å¾´ç¹ãããã³ã°ããã¦ãè¦å·®ããä¸è§æ¸¬éã§å¥¥è¡ããæ±ãããã¹ãã¬ãªãã¸ã§ã³ã精度ãæªãçç±ã®ä¸ã¤ã¨ãã¦ãç¹å¾´ç¹ãããã³ã°ã§ãããããªããã¨ããããã¨ãããã¨ã¨ãç¹å¾´ç¹æ½åºã§ãè²ãåä¸ãªã©ã®å ´æã¯ç¹å¾´ç¹ããªã奥è¡ããåãããªãã¨ããï¼ã¤ãã¡ã¤ã³ã
ããã§ãKinectã§ã¯ã赤å¤ç·ã¬ã¼ã¶ã¼ã§ç¹å¾´ã®ãããã¿ã¼ã³ãç
§å°ã赤å¤ç·ã«ã¡ã©ã§ãã¿ã¼ã³ãèªèããã¿ã¼ã³ç
§å°ã®çºå°ä½ç½®ã¨èµ¤å¤ç·ã«ã¡ã©ã®ä½ç½®ã10cmã»ã©æ°´å¹³ã«ããã¦ããã®ã§ããã®è¦å·®ï¼å·¦ç®ãç
§å°ãå³ç®ãã«ã¡ã©ã¿ãããªæãï¼ã§ãä¸è§æ¸¬éã§å¥¥è¡ããæ±ãã¦ããã¨æããããããã«ããç¹å¾´ç¹ãããã³ã°ã¯ç°¡åã§ãã¹ãå°ãªããã¾ããã«ã©ã¼ã®ã«ã¡ã©ã§èªèã§ãªãã®ã§ãè²ãåä¸ã§ãé¢ä¿ããªãã
ãã°ãããã¢ã¤ãã¢ã ã
ãã¨ã¯ãKinectå
ã«GPUç¸å½ã®ããã»ããµãå
¥ã£ã¦ããã®ããç¹å¾´ç¹ãããã³ã°ã¨ã奥è¡ãè¨ç®ããã¼ãã¦ã§ã¢ã§è¨ç®ããã¦ããã£ã½ãã
Kinectã§å¤¢ãè¨ãã
ãã¼ãKinectã¯ããããã¤ãã°ãã£ã¬ã³ã¸ã§ãæ¥å¹´ã¯Kinectç©ããããããå¢ããããããªãã§ããããããªãããç¾å¨ãã¤ãã°ãã£ã¬ã³ã¸ã§é害ç©ã»ã³ãµã¼ã¨ãã¦äººæ°ãªã®ãåé½é»æ©ã®ã¬ã¼ã¶ã¼ã¬ã³ã¸ãã¡ã¤ã³ã(LRF) Top-URGã¨ãã§ãããããã¯å®ä¾¡ã40ä¸ãã¹ãã£ã³æ¹åã¯1次å
ã§ãå¾ããããã¼ã¿ã¯2次å
ã
ãã£ã½ãKinectã¯ãã¹ãã£ã³ã2次å
ã§ãå¾ããããã¼ã¿ã¯3次å
ãå®ä¾¡ã15,000åã»ã©ã
Kinectã使ãã°é害ç©åé¿ãã§ãããã
ãã ããTop-URGã¯ãè·é¢ã30mé£ãã§ã30må
ã§ã誤差10mm以ä¸ã¨ããé©ç°ã®ç²¾åº¦ãªã®ã«å¯¾ãã¦ãKinectã¯æããã»ã³ã·ã³ã°ç¯å²ã5mã¨ã10mã¨ãï¼å±å
ã§éã¶ç¨ã ãããï¼ã§ãããã¨æããããã誤差ã¯ãã¹ãã¬ãªãã¸ã§ã³ã¨ä¼¼ãä»çµã¿ã¨æãããã®ã§é ãã¨ããã»ã©èª¤å·®ãã§ãã®ã§ã¯ãªãããªãã¾ãã§ãè¿ã3m以ä¸ã¨ãããåããã°é害ç©åé¿ã§ããã®ã§ãããããã®ä¾¡æ ¼ããã£ã¨ä¸ããããã
Kinectãã¤ãã£ãã¢ã¼ã·ã§ã³ãã£ããã£ã¨ããKinectãã«ã³ãã«ç©ãã ã¨ããKinectãã¯ã¢ããã³ãã¿ã¼ï¼AR Droneã¿ãããªãã¤ï¼ã«ç©ãã ã¨ããã©ãã©ããã¥ã¼ã¹ãå±ãã¾ãã
楽ããæ代ã«ãªãã¾ããã
KinectApp Source Code
åãããã£ã¨åæ¥ã§æ¸ããKinectApp.hã¨KinectApp.cppãå
¬éãã¾ããBSDã©ã¤ã»ã³ã¹ã§å
¬éãã¾ãã
ããã¸ã§ã¯ããã¡ã¤ã«ã¯ããã¡ãï¼http://www.asahi-net.or.jp/~qs7e-kmy/robot/KinectTest20101218.zip
KinectApp.h
#ifndef __KINECT_APP_H__ #define __KINECT_APP_H__ #define DEG2RAD(x) ((x)*M_PI/180.0) class KinectApp: public Kinect::KinectListener { private: static const int KINECT_W=Kinect::KINECT_DEPTH_WIDTH; static const int KINECT_H=Kinect::KINECT_DEPTH_HEIGHT; static const char FLAG_POINT=(1<<0);//ç¹ãã static const char FLAG_RIGHT=(1<<1);//å³ã¨ãã¸ãã static const char FLAG_DOWN=(1<<2);//ä¸ã¨ãã¸ãã Kinect::KinectFinder* mKinectFinder;//KinectFinder Kinect::Kinect* mKinect;//Kinect float mYaw;//ã«ã¡ã©ã¨ã¼è§(degree) float mPitch;//ã«ã¡ã©ãããè§(degree) float mDistance;//ã«ã¡ã©è·é¢ unsigned short mDepthBuffer[KINECT_W * KINECT_H];//depth buffer unsigned char mColorBuffer[Kinect::KINECT_COLOR_WIDTH * Kinect::KINECT_COLOR_HEIGHT * 3];//color buffer float mFar;//ã«ããããå¾ãã®è·é¢ float mDepthFact;//奥è¡ãæ¹åã®ã¹ã±ã¼ã« //ã³ã³ã¹ãã©ã¯ã¿ KinectApp(){ mKinectFinder=NULL; mKinect=NULL; mYaw=0.0f; mPitch=0.0f; mDistance=400.0f; memset(mDepthBuffer,0,sizeof(mDepthBuffer)); memset(mColorBuffer,0,sizeof(mColorBuffer)); mDepthFact=600.f; mFar=mDepthFact/4.0f; } public: //ã¤ã³ã¹ã¿ã³ã¹åå¾ï¼ã·ã³ã°ã«ãã³ï¼ static KinectApp* GetApp(); //ãã¹ãã©ã¯ã¿ ~KinectApp(){ if(mKinect!=NULL){ mKinect->SetLedMode(Kinect::Led_Off); mKinect->RemoveListener(this); //delete mKinect;//mKinectã¯KinectFinderãåé¤ããã®ã§ã¢ããªã¯åé¤ããªã } mKinect=NULL; if(mKinectFinder!=NULL){ delete mKinectFinder; } } //Kinectã®åæå bool InitKinect(){ mKinectFinder=new Kinect::KinectFinder(); if(mKinectFinder==NULL){ printf("error init KinectFinder...\n"); return false; } if (mKinectFinder->GetKinectCount() < 1) { printf("Unable to find Kinect devices... Is one connected?\n"); return false; } mKinect = mKinectFinder->GetKinect(); if (mKinect == NULL) { printf("error getting Kinect...\n"); return false; } // register the listener with the kinect. Make sure you remove the // listener before deleting the instance! A good place to unregister // would be your listener destructor. mKinect->AddListener(this); // SetMotorPosition accepts 0 to 1 range mKinect->SetMotorPosition(1); // Led mode ranges from 0 to 7, see the header for possible values mKinect->SetLedMode(Kinect::Led_Yellow); // Grab 10 accelerometer values from the kinect float x,y,z; for (int i =0 ;i<10;i++){ if (mKinect->GetAcceleroData(&x,&y,&z)) { printf("accelerometer reports: %f,%f,%f\n", x,y,z); } Sleep(5); } return true;//success } //glut æç»ã¤ãã³ã static void glutOnDraw(); //glut ãã¼ã¤ãã³ã static void glutOnKeyPress(unsigned char key, int x, int y); //OpenGLã®åæå bool InitDisplay(int argc, char **argv){ GLfloat light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; /* Red diffuse light. */ GLfloat light_position[] = {1.0f, 1.0f, 10.0f, 0.0f}; /* Infinite light location. */ GLfloat lightAmbient[] = {0.2f, 0.2f, 0.2f, 1.0}; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("KinectApp"); glutReshapeWindow(800,600); glutKeyboardFunc(KinectApp::glutOnKeyPress); glutDisplayFunc(KinectApp::glutOnDraw); /* Enable a single OpenGL light. */ glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Setup the view of the cube. */ glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 90.0, /* aspect ratio */ 800.f/600.f, /* Z near */ 1.0, /* Z far */ 1000.0f); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, mDistance, /* eye is at (0,0,5) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.); /* up is in positive Y direction */ return true;//success } //Kinectåæã¤ãã³ã virtual void KinectDisconnected(Kinect::Kinect* kinect) { printf("Kinect disconnected!\n"); } //ããã¹ãããã¡ã®æå°å¤æ大å¤ãæ±ãã void calculateMinMaxDepth(unsigned short* oMin, unsigned short* oMax){ unsigned short min=65535; unsigned short max=0; for(int j=0;j<KINECT_H;j++){ for(int i=0;i<KINECT_W;i++){ unsigned short d=mDepthBuffer[j*KINECT_W+i]; if(d<min){ min=d; } if(d>max){ max=d; } } } *oMin=min; *oMax=max; } // è·é¢ãã¼ã¿åä¿¡ã¤ãã³ã virtual void DepthReceived(Kinect::Kinect* kinect) { kinect->ParseDepthBuffer(); // kinect->mDepthBufferãä»ã ãæå¹ memcpy(this->mDepthBuffer,kinect->mDepthBuffer,sizeof(this->mDepthBuffer)); glutPostRedisplay(); } // ã«ã©ã¼ãã¼ã¿åä¿¡ã¤ãã³ã virtual void ColorReceived(Kinect::Kinect* kinect) { kinect->ParseColorBuffer(); // kinect->mColorBufferãä»ã ãæå¹ memcpy(this->mColorBuffer,kinect->mColorBuffer,sizeof(this->mColorBuffer)); } //é³å£°åä¿¡ã¤ãã³ã virtual void AudioReceived(Kinect::Kinect* kinect) { } //ãã¼ã¤ãã³ã void OnKeyPress(unsigned key){ KinectApp* app = KinectApp::GetApp(); printf("key=%d\n",key); switch (key) { case 27://ESCãã¼ã®ã¨ã delete app; exit(0); case 97://a mYaw+=10.0f; glutPostRedisplay(); break; case 100://d mYaw-=10.0f; glutPostRedisplay(); break; case 119://w mPitch+=10.f; glutPostRedisplay(); break; case 115://s mPitch-=10.0f; glutPostRedisplay(); break; case 102://f mDepthFar mFar += 10.0f; printf("mFar=%7.0f\n",mFar); break; case 103://g mDepthFar mFar -= 10.0f; printf("mFar=%7.0f\n",mFar); break; } } //3Dã¹ã¯ãªã¼ã³ã®æç»(é£ã®ãã¯ã»ã«ã¨ãã£ã¤ãã¦ãã) void draw3DScreen2(void){ unsigned short min=482,max=2047; //calculateMinMaxDepth(&min,&max); float fDiv=(float)(max-min); //ããã¹ãæ±ãã float zFact = 600.0f; float* fDepth=(float*)malloc(sizeof(float)*KINECT_W*KINECT_H); for(int j=0;j<KINECT_H;j++){ for(int i=0;i<KINECT_W;i++){ int d=mDepthBuffer[KINECT_W*j+i]; fDepth[KINECT_W*j+i] = -zFact*(float)(d-min)/fDiv+zFact/2.0f; } } //QUADæç» float cx=(float)(KINECT_W)/2.0f; float cy=(float)(KINECT_H)/2.0f; int dx=-25;//ãã£ãªãã¬ã¼ã·ã§ã³ int dy=10; for(int j=0;j<KINECT_H-1;j++){ for(int i=0;i<KINECT_W-1;i++){ //ããã¹ãã§ã㯠if(fDepth[KINECT_W* j +i]<mFar){ continue; } float depth[4]; depth[0]=fDepth[KINECT_W* j +i]; depth[1]=fDepth[KINECT_W*(j+1)+i]; depth[2]=fDepth[KINECT_W*(j+1)+i+1]; depth[3]=fDepth[KINECT_W* j +i+1]; float min=60000.0f; float max=-60000.0f; for(int k=0;k<4;k++){ min=min(depth[k],min);max=max(depth[k],max); } if(max-min>50.0f){//åå¾ã«ä¼¸ã³ã¦ããããªã´ã³ã¯è¡¨ç¤ºããªã continue; } //ã«ã©ã¼åå¾ unsigned char cR,cG,cB; if(i+dx<0 || i+dx>=Kinect::KINECT_COLOR_WIDTH || j+dy<0 || j+dy>=Kinect::KINECT_COLOR_HEIGHT){//ã«ã©ã¼ãããã¡ã®å¤ã®ã¨ã cR=cG=cB=0; } else {//ä¸ã®ã¨ã unsigned char* p = &mColorBuffer[((j+dy)*Kinect::KINECT_COLOR_WIDTH+(i+dx))*3]; cR=*(p++), cG=*(p++), cB=*(p++); } float color[3]; color[0]=cR/255.0f; color[1]=cG/255.0f; color[2]=cB/255.0f; //ä½ç½®è¨ç® float x[4],y[4]; x[0]=(float)i -cx; y[0]=(float)-j +cy; x[1]=(float)i -cx; y[1]=(float)-j-1.0f+cy; x[2]=(float)i+1.0f-cx; y[2]=(float)-j-1.0f+cy; x[3]=(float)i+1.0f-cx; y[3]=(float)-j +cy; //æç» glBegin(GL_QUADS); glMaterialfv(GL_FRONT,GL_DIFFUSE,color); glNormal3f(0.0f,0.0f,1.0f); glVertex3f(x[0],y[0],depth[0]); glVertex3f(x[1],y[1],depth[1]); glVertex3f(x[2],y[2],depth[2]); glVertex3f(x[3],y[3],depth[3]); glEnd(); } } free(fDepth); } //æç»ã¤ãã³ã void OnDraw(){ glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); double yaw = DEG2RAD(mYaw); double pitch = DEG2RAD(mPitch); double r = mDistance; gluLookAt(r*sin(yaw)*cos(pitch), r*sin(pitch), r*cos(yaw)*cos(pitch), /* eye is at (0,0,5) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.); /* up is in positive Y direction */ draw3DScreen2(); glutSwapBuffers(); } }; #endif//__KINECT_APP_H__
KinectApp.cpp
// KinectApp.cpp : ã¢ããªã¯ã©ã¹ // #include "stdafx.h" #include "Vector.h" #include "KinectApp.h" //ã°ãã¼ãã«å¤æ° static KinectApp* g_app=NULL; //ã¤ã³ã¹ã¿ã³ã¹åå¾ï¼ã·ã³ã°ã«ãã³ KinectApp* KinectApp::GetApp(){ if(g_app==NULL){ g_app = new KinectApp(); } return g_app; } //glut æç»ã¤ãã³ã void KinectApp::glutOnDraw(void) { KinectApp::GetApp()->OnDraw(); } //glut ãã¼ã¤ãã³ã void KinectApp::glutOnKeyPress(unsigned char key, int x, int y) { KinectApp::GetApp()->OnKeyPress(key); } //ã¨ã³ããªã¼ãã¤ã³ã int _tmain(int argc, char **argv) { KinectApp* app = KinectApp::GetApp(); app->InitDisplay(argc,argv); app->InitKinect(); glutMainLoop(); return 0; }
URL:ãã®è¨äºãåèã«ãªã£ãã¨è¨ãæ¹ãibisMailãã¿ã¦ãã£ã¦ãã ããm(_ _)m こちら