【问题标题】:draw graphics over kinect video image in processing 3.0在处理 3.0 中在 kinect 视频图像上绘制图形
【发布时间】:2016-06-21 10:17:43
【问题描述】:

我正在阅读 Greg Borenstein 的书“让事物看得见”,并想出了如何创建一个光标来跟踪最接近 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);
  };

【问题讨论】:

    标签: computer-vision processing kinect


    【解决方案1】:

    我相信您问的是如何在 Processing 中创建粒子轨迹。这实际上与 kinect 没有任何关系——对 background() 的简单调用也会覆盖您的任何粒子。所以你目前有这样的东西:

    void setup(){
      size(500, 500);
    }
    
    void draw(){
    
      background(0);
    
      ellipse(mouseX, mouseY, 10, 10);
    }
    

    您正在屏幕上绘制一些东西(在您的代码中,一个红球,在我的代码中,一个椭圆),但它被清除了(在您的代码中,kinect 视频,在我的代码中,调用 @987654324 @)。您是在问如何制作它,即使在您绘制背景之后,椭圆也会留在屏幕上。

    答案是这样的:您需要将轨迹的位置存储在数据结构中,然后每帧重绘它们。

    一个简单的方法是创建一个ArrayListPVector 实例。要将粒子添加到轨迹,只需将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);
      }
    
    }
    

    但是,这条轨迹会不断增长,最终您将耗尽内存来保存每个点。所以为了防止你的踪迹这样做,你需要限制它的大小:

    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));
    
      if(trail.size() > 10){
        //trail is too long, remove the oldest point
        trail.remove(0);
      }
    
      //draw the trail
      for(PVector p : trail){
        ellipse(p.x, p.y, 10, 10);
      }
    
    }
    

    从这里您可以做一些更有趣的事情:为轨迹中的每个点赋予动量或颜色,或将其淡出,或减小其宽度。但基本情况是这样的:您必须将粒子存储在数据结构中,更新该数据结构以添加或删除粒子,然后遍历该数据结构以绘制轨迹。

    【讨论】:

    • 感谢凯文的回复。我想我不清楚我要做什么,所以我将我的代码添加到我的问题中。在您的示例中,我可以将 mouseX 和 mouseY 替换为我的变量 closeX 和 mosty 并将 background(0) 替换为 image(kinect.getVideoImage(), 0, 0) 吗?
    • @AaronPennington 当您尝试这样做时发生了什么?另外,请注意我的代码是minimal reproducible example,这也是您应该尝试发布的内容。尝试将您的问题缩小到尽可能少的行,而不是发布您的整个草图。
    • 好的,谢谢。我会试着在这里清理一下。当我尝试它时,它只是闪烁并溅射。我认为视频正在绘制动画图形,因此它覆盖了旧帧,因为它们都在 draw() 函数中。我要么需要两个 draw() 函数,要么需要 draw() 函数下的另一个函数来处理视频源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2023-03-16
    • 2017-03-04
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    相关资源
    最近更新 更多