Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create more than one window of a single sketch in Processing

How to create more than one window of a single sketch in Processing?

Actually I want to detect and track a particular color (through webcam) in one window and display the detected co-ordinates as a point in another window.Till now I'm able to display the points in the same window where detecting it.But I want to split it into two different windows.

like image 716
Saikat Avatar asked Dec 22 '13 15:12

Saikat


3 Answers

You need to create a new frame and a new PApplet... here's a sample sketch:

import javax.swing.*; 
SecondApplet s;
void setup() {
  size(640, 480);
  PFrame f = new PFrame(width, height);
  frame.setTitle("first window");
  f.setTitle("second window");
  fill(0);
}
void draw() {
  background(255);
  ellipse(mouseX, mouseY, 10, 10);
  s.setGhostCursor(mouseX, mouseY);
}
public class PFrame extends JFrame {
  public PFrame(int width, int height) {
    setBounds(100, 100, width, height);
    s = new SecondApplet();
    add(s);
    s.init();
    show();
  }
}
public class SecondApplet extends PApplet {
  int ghostX, ghostY;
  public void setup() {
    background(0);
    noStroke();
  }

  public void draw() {
    background(50);
    fill(255);
    ellipse(mouseX, mouseY, 10, 10);
    fill(0);
    ellipse(ghostX, ghostY, 10, 10);
  }
  public void setGhostCursor(int ghostX, int ghostY) {
    this.ghostX = ghostX;
    this.ghostY = ghostY;
  }
}
like image 194
Petros Koutsolampros Avatar answered Nov 06 '22 03:11

Petros Koutsolampros


One option might be to create a sketch twice the size of your original window and just offset the detected coordinates by half the sketch's size.

Here's a very rough code snippet (assumming blob will be a detected color blob):

int camWidth = 320;
int camHeight = 240;
Capture cam;

void setup(){
  size(camWidth * 2,camHeight);
  //init cam/opencv/etc.
}
void draw(){
  //update cam and get data
  image(cam,0,0);
  //draw 
  rect(camWidth+blob.x,blob.y,blob.width,blob.height);
}

To be honest, it might be easier to overlay the tracked information. For example, if you're doing color tracking, just display the outlines of the bounding box of the tracked area.

If you really really want to display another window, you can use a JPanel. Have a look at this answer for a running code example.

like image 25
George Profenza Avatar answered Nov 06 '22 05:11

George Profenza


I would recommend using G4P, a GUI library for Processing that has some functionality built in for handling multiple windows. I have used this before with a webcam and it worked well. It comes with a GWindow object that will spawn a window easily. There is a short tutorial on the website that explains the basics.

I've included some old code that I have that will show you the basic idea. What is happening in the code is that I make two GWindows and send them each a PImage to display: one gets a webcam image and the other an effected image. The way you do this is to augment the GWinData object to also include the data you would like to pass to the windows. Instead of making one specific object for each window I just made one object with the two PImages in it. Each GWindow gets its own draw loop (at the bottom of the example) where it loads the PImage from the overridden GWinData object and displays it. In the main draw loop I read the webcam and then process it to create the two images and then store them into the GWinData object.

Hopefully that gives you enough to get started.

import guicomponents.*;
import processing.video.*;

private GWindow window;
private GWindow window2;

Capture video;

PImage sorted;
PImage imgdif; // image with pixel thresholding

MyWinData data;

void setup(){

  size(640, 480,P2D); // Change size to 320 x 240 if too slow at 640 x 480

  // Uses the default video input, see the reference if this causes an error
  video = new Capture(this, 640, 480, 24);
  numPixels = video.width * video.height;

  data = new MyWinData();

  window = new GWindow(this, "TEST", 0,0, 640,480, true, P2D);
  window.isAlwaysOnTop();
  window.addData(data);
  window.addDrawHandler(this, "Window1draw");

  window2 = new GWindow(this, "TEST", 640,0 , 640,480, true, P2D);
  window2.isAlwaysOnTop();
  window2.addData(data);
  window2.addDrawHandler(this, "Window2draw");

  loadColors("64rev.csv");
  colorlength = mycolors.length;
  distances = new float[colorlength];

  noCursor(); 
}

void draw()
{
    if (video.available()) 
    {
      background(0);
      video.read();

      image(video,0,0);
      loadPixels();

      imgdif = get(); // clones the last image drawn to the screen v1.1     
      sorted = get();
      /// Removed a lot of code here that did the processing

      // hand data to our data class to pass to other windows
      data.sortedimage = sorted;
      data.difimage = imgdif;

    }
}

class MyWinData extends GWinData {
   public PImage sortedimage; 
   public PImage difimage;

   MyWinData(){
      sortedimage = createImage(640,480,RGB); 
      difimage = createImage(640,480,RGB);
    }
}


public void Window1draw(GWinApplet a, GWinData d){
  MyWinData data = (MyWinData) d;
  a.image(data.sortedimage, 0,0);
}


public void Window2draw(GWinApplet a, GWinData d){
  MyWinData data = (MyWinData) d;
  a.image(data.difimage,0,0);
}
like image 1
Adam Tindale Avatar answered Nov 06 '22 03:11

Adam Tindale