simpleopenni point cloud program with Kinect - processing

I am trying to use processing to get the point cloud. But it turn out that it does not work
import SimpleOpenNI.*;
import processing.opengl.*;
SimpleOpenNI kinect;
void setup()
{
size( 1024, 768, OPENGL);
kinect = new SimpleOpenNI( this );
kinect.enableDepth();
}
void draw()
{
background( 0);
kinect.update();
translate( width/2, height/2, -1000);
rotateX( radians(180));
stroke(255);
PVector[] depthPoints = kinect.depthMapRealWorld();
//the program get stucked in the for loop it loops 307200 times and I don't have any points output
for( int i = 0; i < depthPoints.length ; i++)
{
PVector currentPoint = depthPoints[i];
point(currentPoint.x, currentPoint.y, currentPoint.z );
}
}

Your code if fine, just tested.
It loops 307200 times because it converts data from the depth image (640x480 = 307200) into 3D positions.
Are you sure you're not getting any errors ?
Also, drawing all the points in Processing is a bit slow, you might want to skip a few.
And as test, try to print out the 1st point and see if the value changes at all (it should)
or if the depth image has any data (isn't black/filled with zeroes):
import SimpleOpenNI.*;
import processing.opengl.*;
SimpleOpenNI kinect;
void setup()
{
size( 1024, 768, OPENGL);
kinect = new SimpleOpenNI( this );
kinect.enableDepth();
}
void draw()
{
background( 0);
kinect.update();
image(kinect.depthImage(),0,0,160,120);//check depth image
translate( width/2, height/2, -1000);
rotateX( radians(180));
stroke(255);
PVector[] depthPoints = kinect.depthMapRealWorld();
//the program get stucked in the for loop it loops 307200 times and I don't have any points output
for( int i = 0; i < depthPoints.length ; i+=4)//draw point for every 4th pixel
{
PVector currentPoint = depthPoints[i];
if(i == 0) println(currentPoint);
point(currentPoint.x, currentPoint.y, currentPoint.z );
}
}

Related

Crossfading multiple images in Processing

Clarifying my last question:
I would like to display, in Processing, many photos fading up and fading down over 15 seconds, with one second between their start times, so there are about 15 images on the screen at a time, at various levels of fading.
This example displays 15 objects, but they all start together:
PImage[] imgs = new PImage[42];
Pic[] pics = new Pic[15];
void setup() {
size(1000, 880);
for (int i = 0; i < pics.length; i++) {
pics[i] = new Pic(int(random(0, 29)), random(0, 800), random(0, height));
}
for (int i = 0; i < imgs.length; i++) {
imgs[i] = loadImage(i+".png");
}
}
void draw() {
background(255);
for (int i = 0; i < pics.length; i++) {
pics[i].display();
}
}
class Pic {
float x;
float y;
int num;
int f = 0;
boolean change = true;
Pic(int tempNum, float tempX, float tempY) {
num = tempNum;
x = tempX;
y = tempY;
}
void display() {
imageMode(CENTER);
if (change)f++;
else f--;
if (f==0||f==555)change=!change;
tint(0, 153, 204, f);
image(imgs[num], x, y);
}
}
If you can fade an image, then you can also cross fade an image by subtracting the fade amount from the maximum fade value (e.g. inverting the fade value).
In your case you're using tint so it's a value from 0-255.
Let's say tint is your variable: 255 - tint would be the inverted value.
Here's a basic sketch you can run that illustrates this (using fill() instead of tint()):
void draw(){
float fade = map(sin(frameCount * 0.03), -1.0, 1.0, 0, 255);
background(0);
noStroke();
// use fade value
fill(192, 0, 192, fade);
ellipse(45, 50, 60, 60);
// invert the fade value (by subtracting it from the max value)
fill(0, 192, 192, 255 - fade);
ellipse(60, 50, 60, 60);
}
Continuing from the previous question and answer you can tweak the code to use an inverted tint value to crossfade. The catch is you'd need to store a reference to the previous image to apply the inverted tint to:
PImage[] imgs = new PImage[42];
ImagesFader fader;
void setup(){
size(255, 255);
frameRate(60);
// load images
for (int i = 0; i < imgs.length; i++) {
imgs[i] = loadImage(i+".png");
}
// setup fader instance
// constructor args: PImage[] images, float transitionDurationSeconds, int frameRate
// use imgs as the images array, transition in and out within 1s per image at 60 frames per second
fader = new ImagesFader(imgs, 3.0, 60);
}
void draw(){
background(0);
fader.draw();
}
class ImagesFader{
int numFrames;
int numFramesHalf;
int frameIndex = 0;
PImage[] images;
int maxImages = 15;
int randomImageIndex;
float randomX, randomY;
PImage previousImage;
float previousX, previousY;
ImagesFader(PImage[] images, float transitionDurationSeconds, int frameRate){
numFrames = (int)(frameRate * transitionDurationSeconds);
numFramesHalf = numFrames / 2;
println(numFrames);
this.images = images;
// safety check: ensure maxImage index isn't larger than the total number of images
maxImages = min(maxImages, images.length - 1);
// pick random index
randomizeImage();
}
void draw(){
updateFrameAndImageIndices();
PImage randomImage = imgs[randomImageIndex];
// isolate drawing style (so only the image fades, not everything in the sketch)
pushStyle();
// if there is a previous image, cross fade it
float tintAlpha = tintFromFrameIndex();
if(previousImage != null){
// invert tint -> max(255) - value
tint(255, 255 - tintAlpha);
image(previousImage, previousX, previousY);
}
// render current random image (on top of the previous one, if any)
tint(255, tintAlpha);
image(randomImage, randomX, randomY);
popStyle();
}
float tintFromFrameIndex(){
int frameIndexToTint = abs(frameIndex - numFramesHalf);
return map(frameIndexToTint, 0, numFramesHalf, 255, 0);
}
void updateFrameAndImageIndices(){
// increment frame
frameIndex++;
// reset frame (if larger than transition frames total)
if(frameIndex >= numFrames){
// update previous image before generating another random image
previousImage = imgs[randomImageIndex];
previousY = randomX;
previousY = randomY;
frameIndex = 0;
// randomize index and position
randomizeImage();
println("fade transition complete, next image: ", randomImageIndex);
}
}
void randomizeImage(){
randomImageIndex = int(random(0, 29));
randomX = random(width);
randomY = random(height);
}
}
The above skeetch might not be 100% accurate (as I don't fully get the randomisation logic), but hopefully it illustrates the mechanism of crossfading.

object releases another smaller object?

Can anyone help me?
So, I'm supposed to have a ball that is moving horizontally, such that every time I press the mouse, a ball would get shoot vertically, then slows down due to friction. The vertical ball would stay in the old position but the player would reset.
How do I go about doing that without using classes?
Here my code so far:
boolean circleupdatetostop = true;
float x = 100;
float yshot = 880;
float speedshot = random(4,10);
float speedx = 6;
void setup() {
size(1280,960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(x,880,80);
if (x > width || x < 0 ) {
speedx = speedx * -1;
}
if (circleupdatetostop) {
x = x + speedx;
}
if (circleupdatetostop == false) {
float locationx = x;
stroke(0);
fill(255,0,255);
circle(locationx,yshot,30);
yshot = yshot - speedshot;
}
}
void mousePressed () {
circleupdatetostop = !circleupdatetostop;
}
I'm not entirely sure if this is what you meant, but you could achieve shooting multiple balls by using ArrayList as well as processing's PVector to better handle the x and y coordinate pairs. If you wanted to look at classes, see this post.
import java.util.*;
// Whether the ball is moving or not
boolean circleupdatetostop = true;
// Information about the main_ball
PVector position = new PVector(100, 880);
PVector speed = new PVector(6, 0);
float diameter = 80;
// Information about the sot balls
ArrayList<PVector> balls_loc = new ArrayList<PVector>();
ArrayList<PVector> balls_speed = new ArrayList<PVector>();
float diameter_shot = 30;
float friction = 0.994;
void setup() {
size(1280, 960);
}
void draw() {
background(255);
stroke(0);
fill(0);
circle(position.x, position.y, diameter);
// Remember to consider the radius of the ball when bouncing off the edges
if (position.x + diameter/2 > width || position.x - diameter/2 < 0 ) {
speed.mult(-1);
}
if (circleupdatetostop) {
position.add(speed);
}
// Cycle through the list updating their speed and draw each ball
for (int i = 0; i<balls_loc.size(); i++) {
balls_speed.get(i).mult(friction+random(-0.05, 0.05));
balls_loc.get(i).add(balls_speed.get(i));
stroke(0);
fill(255, 0, 255);
circle(balls_loc.get(i).x, balls_loc.get(i).y, diameter_shot);
}
}
void mousePressed(){
// Add a new ball to be drawn
if(circleupdatetostop){
balls_loc.add(new PVector(position.x, position.y));
balls_speed.add(new PVector(0, random(-4, -10)));
}
circleupdatetostop = !circleupdatetostop;
}

Processing P3D Animation leaving artifacts behind

I am trying to make a spinning cube in Processing's P3D with this code:
int sizes = 500;
int rotation = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
lights();
translate(sizes/2, sizes/2, 0);
rotateY(rotation * (PI/180));
rotateX(rotation * (PI/180));
background(0);
box(sizes/2);
rotation = (rotation + 1);
}
When I run it the cube does spin as I wanted, but there are strange 'artifacts' (for lack of a better name) left behind its edges.
What causes this issue, and can it be solved?
I tried this and it worked. Maybe instead of using backround(0), set every pixel to black like the background function does manually.
int sizes = 500;
int rotation = 0;
void setup() {
size(500, 500, P3D);
}
void draw() {
fill(255);
lights();
translate(sizes/2, sizes/2, 0);
rotateY(rotation * (PI/180));
rotateX(rotation * (PI/180));
loadPixels();
for(int i = 0; i < pixels.length; i++) pixels[i] = color(0);
box(sizes/2);
rotation = (rotation + 1);
}

Overlapping issue in P3D when rotating

I'd like to rotate a cube in P3D and my code uses live sensor data to do that.
The problem is the previous orientations of the cube are always visible and overlap (as you can see in this image: http://i.stack.imgur.com/txXw6.jpg), which I don't want. I already tried the functions "hint(DISABLE_OPTIMIZED_STROKE)" and "hint(ENABLE_DEPTH_TEST)", which did nothing. Besides the hint functions I found nothing on a similar issue.
How can I render ONLY the current orientation?
import processing.serial.*;
import toxi.geom.*;
Serial myPort;
float qW;
float qX;
float qY;
float qZ;
float[] axis = new float[4];
Quaternion quat = new Quaternion(1, 0, 0, 0);
void setup()
{
size(600, 400, P3D);
myPort = new Serial(this, "COM3", 9600);
background(0);
lights();
}
void draw()
{
serialEvent();
quat.set(qW, qX, qY, qZ);
axis = quat.toAxisAngle();
pushMatrix();
translate(width/2, height/2, -100);
rotate(axis[0], axis[1], axis[2], axis[3]);
noFill();
stroke(255);
box(330, 200, 40);
popMatrix();
}
void serialEvent()
{
int newLine = 13; // new line character in ASCII
String message;
do
{
message = myPort.readStringUntil(newLine); // read from port until new line
if (message != null)
{
String[] list = split(trim(message), " ");
if (list.length >= 4)
{
qW = float(list[0]);
qX = float(list[1]);
qY = float(list[2]);
qZ = float(list[3]);
}
}
} while (message != null);
}
It looks like you're not clearing the frame buffer. Try adding background(0); as the first line in draw();:
void draw()
{
//clear background
background(0);
serialEvent();
quat.set(qW, qX, qY, qZ);
axis = quat.toAxisAngle();
pushMatrix();
translate(width/2, height/2, -100);
rotate(axis[0], axis[1], axis[2], axis[3]);
noFill();
stroke(255);
box(330, 200, 40);
popMatrix();
}
Off topic, it might worth checking out serialEvent().
You could do something like this in setup()
myPort = new Serial(this, "COM3", 9600);
myPort.bufferUntil('\n');
you shouldn't need to call serialEvent() in draw(), the serial library will do that, as it's buffering.
Then in serialEvent() hopefully you can get away with just:
String message = myPort.readString();
if(message !=null){
String[] list = split(trim(message), " ");
if (list.length >= 4)
{
qW = float(list[0]);
qX = float(list[1]);
qY = float(list[2]);
qZ = float(list[3]);
}
}

Making a fading trail in processing

I have a circle that is moving across the screen, what i need is to be able to make that circle leave a line behind it that fades after a second or so. I'm using Processing.
Can't speak for its efficiency but I imagine one way to do it would be to keep the old positions in an ArrayList? You can then draw lines between each point, as long as you push the current position each frame and remove the least recent. Hope it helps!
PVector circlePosition;
ArrayList<PVector> circleTrail;
int trailSize = 10;
void setup() {
size(500, 500);
circlePosition = new PVector(width*0.5, width*0.5);
circleTrail = new ArrayList<PVector>();
}
void draw() {
background(255);
int trailLength;
circlePosition = new PVector(mouseX, mouseY);
circleTrail.add(circlePosition);
trailLength = circleTrail.size() - 2;
println(trailLength);
for (int i = 0; i < trailLength; i++) {
PVector currentTrail = circleTrail.get(i);
PVector previousTrail = circleTrail.get(i + 1);
stroke(0, 255*i/trailLength);
line(
currentTrail.x, currentTrail.y,
previousTrail.x, previousTrail.y
);
}
ellipse(circlePosition.x, circlePosition.y, 10, 10);
if (trailLength >= trailSize) {
circleTrail.remove(0);
}
}
I also can't speak to the efficiency of my method, but the way I've done it is by drawing a rectangle over your entire sketch each time with an also set to a low value (like 25 or so). This results in the objects from previous draw() cycles looking 'faded'. For example:
int i = 0;
void setup(){
size(500,500);
smooth();
noStroke();
background(255);
}
void draw(){
fill(255,25);
rect(0,0,width,height);
fill(0);
ellipse(width/2 + i,height/2 + i,50,50);
delay(100);
i+=10;
}

Resources