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