SimpleOpenNI / Kinect: контроль цвета сцены / карты глубины

[Контекст] Я помогаю аспиранту (МИД) в художественном проекте:

Я пытаюсь управлять выходным цветом генерации глубины, чтобы значения Red, Green и Blue можно было независимо контролировать. Желаемым конечным результатом игры является то, что каждое сгенерированное значение глубины карты может быть изменено на различные оттенки пурпурного (255,0255), так что каждый пользователь SimpleOpenNI будет выглядеть дифференцированным.

До сих пор я не нашел ни способа сделать это в файле pde, ни правильного способа изменить класс SimpleOpenNI для достижения той же цели. - По какой-либо причине вызов tint() изменяет альфа-значение холста, но, похоже, не корректирует значения цвета.

Любой применимый совет будет оценен.

Ресурсы: SimpleOpenNI Souce Мой pde:

import SimpleOpenNI.*;


SimpleOpenNI  context;

void setup()
{
  context = new SimpleOpenNI(this);

  // enable depthMap generation
  if(context.enableScene() == false)
  {
     println("Can't open the sceneMap, maybe the camera is not connected!"); 
     exit();
     return;
  }

  frameRate(30);
  background(128);
  size(context.sceneWidth() , context.sceneHeight()); 
}

void draw()
{

  // update the cam
  context.update(); 

  // draw irImageMap && Sets frame size.
  image(context.sceneImage(),25,25, 590,430);

  // "blend" shapes BG & previous the frame
   tint(#ED145B, 125);

}

1 ответ

Решение

Помимо sceneImage(), SimpleOpenNI также предоставляет метод, называемый sceneMap() который принимает int[] в качестве входных данных. Он заполняет значения в массиве, которые сопоставляются конкретному пользователю, с номером, соответствующим этому пользователю.

Например, если у вас нет пользователей, массив sceneMap будет заполнен нулями (например,[0,0,0.....0]), если у вас есть 1 пользователь, некоторые элементы будут заполнены 1 для пикселей, принадлежащих этому пользователю (например, [0,0,0,1,1,...1,0,0,0,1,0...etc.]) и так далее.

Вы можете попытаться выполнить некоторую замену цвета в PImage, но это не очень гибко (что, если у вас также включена карта глубины?), И вы полагаетесь на жестко закодированные значения для каждого пользователя (R,B,G,C).,M,Y, который когда-либо порядок может быть в SimpleOpenNI), поэтому sceneMap() это более гибкий вариант.

Вот прокомментированный пример того, как использовать это:

import SimpleOpenNI.*;

SimpleOpenNI  context;

int[] sceneMap;//this will store data about the scene (bg pixels will be 0, and if there are any users, they will have the value of the user id - e.g. if there are no users, the array will be filled with zeros, if there is one user, some array entries will be equal to 1, etc. the size of the array is the same as the number of pixels in scene image, so it's easy to use with the pixels[] of a PImage
PImage myUserImage;//this is where we'll draw the user
int user1Colour = color(180,130,30);//change to whatever you like

void setup()
{
  context = new SimpleOpenNI(this);
  context.enableScene();

  background(200,0,0);
  size(context.sceneWidth() , context.sceneHeight());
  //set scene map array
  sceneMap = new int[context.sceneWidth()*context.sceneHeight()];
  //create the image to draw the user into, by default it will be filled black
  myUserImage = createImage( context.sceneWidth() , context.sceneHeight(), RGB );
}

void draw()
{
  context.update(); 

  // // gives you a label map, 0 = no person, 0+n = person n - tell OpenNI to update the numbers in the array
  context.sceneMap(sceneMap);
  //clear myUserImage - fill everything with black
  Arrays.fill(myUserImage.pixels,color(0));//We've never used Arrays.fill() before, but all it does is it loops through all elements on an array you pass and sets a value you want for each element - fills an array with a value
  for(int i = 0 ; i < myUserImage.pixels.length; i++){
    //check if there is a user for the current pixel, if so, use our custom colour for the pixel at this index
    if(sceneMap[i] > 0) myUserImage.pixels[i] = user1Colour;
  }
  myUserImage.updatePixels();

  //display image
  image(myUserImage,0,0);
}

В долгосрочной перспективе, если вы хотите обслуживать нескольких пользователей, стоит написать базовый класс утилит:

import SimpleOpenNI.*;

SimpleOpenNI  context;

SceneMapper sceneMap;

void setup()
{
  context = new SimpleOpenNI(this);
  context.enableScene();

  background(200,0,0);
  size(context.sceneWidth() , context.sceneHeight());

  sceneMap = new SceneMapper(context);
}

void draw()
{
  context.update(); 
  sceneMap.update();
  //display image
  image(sceneMap.scene,0,0);
}
class SceneMapper{
  PImage scene;//this is a PImage where we'll actually draw the user with what colour we want
  int[] sceneMap;//this will store scene data - an array of ints which has the same length as context.sceneImage().pixels, the only difference is, sceneImage already has colours set, while scene map has numbers representing user(1,2,3etc.) on top of background(0s)
  int numPixels;//total number of pixels, we only store it so we can reuse it
  color bg;//background colour
  color[] users = {color(255),color(192),color(127),color(64),color(32)};//fill colours for users

  SceneMapper(SimpleOpenNI context){
    numPixels = context.sceneWidth()*context.sceneHeight();
    sceneMap = new int[numPixels];//init scene nap array
    scene = createImage( context.sceneWidth(), context.sceneHeight(), RGB );//create a PImage to display scene data
    scene.loadPixels();  
    bg = color(0);
  }
  void update(){
    context.sceneMap(sceneMap);//ask SimpleOpenNI to store scene map data into our array
    Arrays.fill(scene.pixels, bg);//clear the image - fill it with the background colours
    for(int i = 0 ; i < numPixels ; i++){//loop through all pixels
      for(int u = 0 ; u < users.length; u++){//loop through user colours
        if(sceneMap[i] > 0) scene.pixels[i] = users[u];//if there are user pixels, use set user colour for those pixels (e.g. pixels with value 1 will use colours stored in users[0], pixels with value 2 will use colour from users[1], etc.) 
      } 
    }
    scene.updatePixels();//we've use pixels, so update the image at the end
  }
}

но это зависит от того, знаком ли ученик с классами, и, учитывая, что это МФА, меньше давления на чистый код и больше давления на выполнение заданий, как я полагаю.

Другие вопросы по тегам