在处理3.0中在kinect视频图像上绘制图形

时间:2016-03-07 18:15:56

标签: computer-vision processing kinect

我正在研究Greg Borenstein的着作“Make Things See”,并想出了如何创建一个跟踪最接近Kinect的运动的光标。现在光标是一个简单的红球。所以我能够跟踪我的手指

image(kinect.getVideoImage(), 0, 0) 

当我将光标球放在按钮区域时,我还创建了将滤镜应用于视频图像的按钮。

它很有趣,但新奇已经用完所以现在我想把光标球变成一个动画图形,使用粒子或类似的东西。这个动画图形应该仍然跟踪我的手指并被绘制在视频图像上。

当我尝试写这个时,图形出错了,因为视频图像不断重绘在粒子上,所以它看起来不正确。

我以为我可以使用capture()方法在图形下绘制视频图像,但我无法弄清楚如何使用Kinect中的视频。

有没有人对如何做到这一点有任何想法?任何帮助将不胜感激。

我的kinect跟踪器和过滤器按钮示例如下。如果您将其复制并粘贴到处理中并插入了kinect,则应该运行它。我为代码缺乏口才而道歉。我还在学习如何编写漂亮的代码。

我想要触发红球的新图形而不是过滤器,可能会应用粒子或其他东西。

//my kinect tracker

import org.openkinect.freenect.*;
import org.openkinect.processing.*;

Kinect kinect;

boolean ir = true;
boolean colorDepth = true;
boolean mirror = true;

float closestValue;  
float closestX;      
float closestY;

// create arrays to store recent closest x- and y-coordinates for averaging
int[] recentXValues = new int[3];
int[] recentYValues = new int[3];

// keep track of which is the current value in the array to be changed
int currentIndex = 0;

float circleButtonX, circleButtonY; // position of circle button
float circleButtonSize; // diameter of circle button
color circleButtonColor; // color of circle button 

void setup() {
  size(640, 480, P3D);
  kinect = new Kinect(this);
  kinect.initDepth();
  kinect.initVideo();
  //kinect.enableIR(ir);
  kinect.enableMirror(mirror);
  kinect.enableColorDepth(colorDepth);

  circleButtonColor = color(0, 0, 255);

}

void draw() {
  closestValue = 1700;

  int[] depthValues = kinect.getRawDepth();

  for(int y = 0; y < 480; y++) {
    for(int x = 0; x < 640; x++) {

      int i = x + y * 640;
      int currentDepthValue = depthValues[i];

      if(currentDepthValue > 0 && currentDepthValue < closestValue) {
        //save its value
        closestValue = currentDepthValue;

        recentXValues[currentIndex] = x;
        recentYValues[currentIndex] = y;
      }
    }
  }

  currentIndex++;
  if(currentIndex > 2) {
    currentIndex = 0;
  }

  // closetX and ClosestY become a running average 
  // with currentX and CurrentY
  closestX = (recentXValues[0] + recentXValues[1] + recentXValues[2]) / 3;
  closestY = (recentYValues[0] + recentYValues[1] + recentYValues[2]) / 3;


  //draw the depth image on the screen
  image(kinect.getVideoImage(), 0, 0);
  fill(0, 0, 250);
  ellipse(75, 75, 100, 100);
  ellipse(200, 75, 100, 100);
  ellipse(75, 200, 100, 100);
  rect(540, 25, 75, 100);

  //buttons
  fill(255,0,0);
  textSize(24);
  text("Invert", 40, 85);
  text("Blur", 50, 210);
  textSize(18);
  text("Threshold", 155, 85);
  text("Stop", 560, 75);
  ellipse(closestX, closestY, 25, 25);

  if (closestX > 25 && closestX < 125 && closestY > 25 && closestY < 125) {
    filter(INVERT);
  };

  if (closestX > 150 && closestX < 250 && closestY > 25 && closestY < 125) {
    filter(THRESHOLD);
  };

  if (closestX > 25 && closestX < 125 && closestY > 150 && closestY < 250) {
  filter(BLUR, 6);
  };


  if (closestX > 540 && closestX < 615 && closestY > 25 && closestY < 100) {
  noLoop();
  loop();
  background(0);
  };

1 个答案:

答案 0 :(得分:0)

我相信你在询问如何在Processing中创建粒子轨迹。这与kinect没有任何关系 - 对background()的简单调用也会覆盖任何粒子。所以你现在有这样的事情:

void setup(){
  size(500, 500);
}

void draw(){

  background(0);

  ellipse(mouseX, mouseY, 10, 10);
}

你正在向屏幕绘制一些东西(在你的代码中,一个红色的球,在我的代码中,一个椭圆),但它被清除了(在你的代码中,kinect视频,在我的代码中,调用{{ 1}})。您正在询问如何制作它,以便即使在绘制背景后椭圆也会保留在屏幕上。

答案是:您需要将跟踪的位置存储在数据结构中,然后每帧重绘一次。

一种简单的方法是创建background(0) ArrayList个实例。要向跟踪添加粒子,只需向PVector添加PVector即可。然后你只需遍历踪迹并绘制每个ArrayList点。

PVector

然而,这条线索会不断增长,你最终会耗尽内存来控制每一点。因此,为了避免这样做,您需要限制其大小:

ArrayList<PVector> trail = new ArrayList<PVector>();

void setup(){
  size(500, 500);
}

void draw(){

  background(0);

  //add to the trail
  trail.add(new PVector(mouseX, mouseY));

  //draw the trail
  for(PVector p : trail){
    ellipse(p.x, p.y, 10, 10);
  }

}

从这里你可以做更好的事情:给你的踪迹中的每个点一个动量或颜色,或淡出它,或减少它的宽度。但基本原理是:您必须将粒子存储在数据结构中,更新该数据结构以添加或移除粒子,然后迭代该数据结构以绘制线索。