2016년 1월 2일 토요일

Processing + Kinect + Syphon을 사용한 VPT 프로젝션 맵핑

Processing + Kinect + Syphon을 사용한 VPT 프로젝션 맵핑을 위해서는, 다음 프로그램 및 라이브러리가 필요하다.



  • Processing 2.2
  • OpenNI 1.96 for Processing
  • Syphon library for Processing (Processing에서 Add library 메뉴에 Syphon 를 검색해 바로 설치할 수 있다)
이를 이용하면, 키넥트를 통해, Processing에서 취득한 3D 포인트 클라우드 데이터를 Syphon을 통해, VPT 7에 출력할 수 있다. 아두이노와 연계한다면, 인터렉티브한 프로젝션 맵핑이 가능하다.


다음은 이와 관련된 소스 코드이다. 


import codeanticode.syphon.*;
import SimpleOpenNI.*;

PGraphics canvas;
SyphonServer server;

SimpleOpenNI context;
float        zoomF =0.3f;
float        rotX = radians(180);  // by default rotate the hole scene 180deg around the x-axis, 
                                   // the data from openni comes upside down
float        rotY = radians(0);

void setup()
{
  size(640, 480,P3D);
  canvas = createGraphics(640, 480, P3D);
  server = new SyphonServer(this, "Processing Syphon by mac");

  context = new SimpleOpenNI(this);
  if(context.isInit() == false)
  {
     println("Can't init SimpleOpenNI, maybe the camera is not connected!"); 
     exit();
     return;  
  }
  
  // disable mirror
  context.setMirror(false);

  // enable depthMap generation 
  context.enableDepth();

  canvas.stroke(255,255,255);
  canvas.smooth();
  canvas.perspective(radians(45),
              float(width)/float(height),
              10,150000);
}

void draw()
{
  // update the cam
  context.update();

  canvas.beginDraw();
  
  canvas.background(0,0,0);

  canvas.translate(width/2, height/2, 0);
  canvas.rotateX(rotX);
  canvas.rotateY(rotY);
  canvas.scale(zoomF);

  int[]   depthMap = context.depthMap();
  int     steps   = 3;  // to speed up the drawing, draw every third point
  int     index;
  PVector realWorldPoint;
  canvas.translate(0,0,-1000);  // set the rotation center of the scene 1000 infront of the camera

  canvas.stroke(255);

  PVector[] realWorldMap = context.depthMapRealWorld();
  
  // draw pointcloud
  canvas.beginShape(POINTS);
  for(int y=0;y < context.depthHeight();y+=steps)
  {
    for(int x=0;x < context.depthWidth();x+=steps)
    {
      index = x + y * context.depthWidth();
      if(depthMap[index] > 0)
      { 
        // draw the projected point
//        realWorldPoint = context.depthMapRealWorld()[index];
        realWorldPoint = realWorldMap[index];
        canvas.vertex(realWorldPoint.x,realWorldPoint.y,realWorldPoint.z);  // make realworld z negative, in the 3d drawing coordsystem +z points in the direction of the eye
      }
      //println("x: " + x + " y: " + y);
    }
  } 
  canvas.endShape();
  
  // draw the kinect cam
  // context.drawCamFrustum();
  
  
  canvas.endDraw();
  image(canvas, 0, 0);
  server.sendImage(canvas);
}


void keyPressed()
{
  switch(key)
  {
  case ' ':
    context.setMirror(!context.mirror());
    break;
  }

  switch(keyCode)
  {
  case LEFT:
    rotY += 0.1f;
    break;
  case RIGHT:
    // zoom out
    rotY -= 0.1f;
    break;
  case UP:
    if(keyEvent.isShiftDown())
      zoomF += 0.02f;
    else
      rotX += 0.1f;
    break;
  case DOWN:
    if(keyEvent.isShiftDown())
    {
      zoomF -= 0.02f;
      if(zoomF < 0.01)
        zoomF = 0.01;
    }
    else
      rotX -= 0.1f;
    break;
  }
}




댓글 5개:

  1. 안녕하세요 키넥트에 대해서 도움좀 받을 수 있을까요?

    답글삭제
    답글
    1. 안녕하세요. 어떤 부분에서 도움이 필요하신가요? 제가 알고 있는 부분은 이야기드릴수 있습니다.

      삭제
    2. ROS를 이용해서 kinect V2 맵핑을 하려고 합니다. 그냥 영상은 나오게 했지만 맵핑하는 법을 몰라서 헤매고 있는데요. 로스나 윈도우를 통해 아두이노와 맵핑하는 방법을 어느 정도 배울 수 있을까요? 어느 정도 지식이 없이 이것저것 하는 중이라 깊이있게 알지 못합니다....

      삭제
    3. 자료를 찾아보면 터틀봇을 이용해서 맵핑을 하는데, 터틀봇 대신 다른 모터를 달아서 아두이노와 키넥트를 연결 후 맵핑하는 방법을 모르겠습니다.

      삭제
    4. 죄송합니다. 정신줄 놓고 살고 있다가, 완전 늦어버렸네요. 늦게나마 참회하는 마음으로 제가 아는 부분에 대해 글 답니다.

      맵핑라면, SLAM말하시는 것 같네요.
      물론 터틀봇 대신 키넥트 연결해 SLAM맵핑 처리할 수 있습니다 (아래 링크 참고).
      https://www.youtube.com/watch?v=a8Zz_HM1i38
      https://www.youtube.com/watch?v=17W8dkzkvWA

      터틀봇 SLAM은 아래에 내용 잘 나와 있습니다(표윤석님 ROS책 참고).
      http://patilnabhi.github.io/portfolio/tbotnav

      SLAM도 여러 종류가 있습니다. 아래 링크는 keypoint를 이용해 맵 생성이 편리한 LSD SLAM입니다.
      http://vision.in.tum.de/research/vslam/lsdslam

      개발에 참고하시길 바랍니다.

      삭제