Awesome, Tunabreath! :D
i’m very excited about this, i’m hoping it will bring rapid development and simple experminting a lot closer for everyone.
i have attached a very simple version of the processing sketch, which is more well-commented, and contains less non-necesary code.
(just the blob detection and drawing the location and outlines of the blobs)
You might want to use this for a starting point for your own sketches, rather than the one i posted earlyer.
Make sure you have the JMyron library with my modified JMyron.jar (get it from http://nuigroup.com/forums/viewthread/1818/ )
And that you have the controlP5 library
Both are available from http://www.processing.org
happy experimenting
import JMyron.*;
import controlP5.*;
//define the JMyron object
JMyron m;
//define a controlp5 opbject
ControlP5 controlP5;
//JMyron's blobtracking example
//Modified and extended for use with an FTIR or similar
//***************IMPORTANT, READ THIS!************************************
//if you haven't downloaded JMyron/webcamextra yet
// you can find it at www.proce55ing.org
//be sure to use my modified version of JMyron.jar
//download it from http://nuigroup.com/forums/viewthread/1818/
//and copy it over the original JMyron.jar file in your processing/libraries folder
//notes:
//ideally, one would blur the incoming image slightly to eliminate noise.
//this should still be implemented.
//preset values
int tracecolor = 255;
int tracetolerance = 40;
void setup(){
//define width and height separately
//we need them for the jmyron object and
//we might do something with these later on.
int w = 320;
int h = 240;
frameRate(24);
size(w,h);
//initialise the JMyron object
m = new JMyron();
//start it with the width and height of the sketch
m.start(w,h);
//turn glob detection on
m.findGlobs(1);
//initialise controlP5
controlP5 = new ControlP5(this);
//make a slider for which grayscale colour to track
controlP5.addSlider("Track_colour",0,255,255,10,10,10,100).setId(1);
//make a slider for which tolerance to use for tracking
controlP5.addSlider("Track_tolerance",0,255,40,10,126,10,100).setId(2);
//make a button to open the webcam settings dialog with
controlP5.addButton("Webcam settings",10,100,215,80,20).setId(3);
}
/**
*the draw event is called at the speed defined by frameRate(int fps);
**/
void draw(){
//clear the sketch by drawing a white background
//(is only needed if you turn the camera view display off)
background (255,255,255,255);
//set the color we want to track
//(dark gray)
// r g b tolerance
m.trackColor(tracecolor,tracecolor,tracecolor,tracetolerance);
//have JMyron fetch new data from the camera
m.update();
//get the current image
//and store it into an array of integers
int[] img = m.image();
//define floats for red green and blue channels
float ir,ig,ib;
//first draw the camera view onto the screen
//comment this piece of code if you don't need to display the camera output
//ebcam image-drawing code
//----------------------------------------------------------
loadPixels();
//web cam image drawing starts here
//itterate through every pixel on the screen
for(int i=0;i<width*height;i++){
/*
//this code inverts all pixels by subtracting their color value from the maximum
//this is not necessary, but allows you to see better where your globs should occur
//on your FTIR screen.
//for some reason, human eyes distinguish white on black better than black on white.
ir = 255-red(img[i]);
ig = 255-green(img[i]);
ib = 255-blue(img[i]);
//add the inverted pixel to an array
pixels[i] = color(ir,ig,ib);
*/
//you can invert the displayed webcam colour by uncommenting the above code and commenting this line)
pixels[i] = img[i];
}
updatePixels();
//webcam image-drawing code ends here
//----------------------------------------------------------
//**********Enmerate and draw BLOB-CENTERS***********//
//initiate a two dimensional array that will hold the blob centers x and y positions
int[][] a;
//fetch them
a = m.globCenters();
//draw them
stroke(255,128,128);
fill(128,0,128,128);
//for every blob center
print("i see " + a.length + " blobs\n");
//itterate through all blobs
for(int i=0;i<a.length;i++){
//output to the console which blob this is
print("blob " + i + " : ");
//if the blob is not exactly at 0 x 0
//(jmyron may have this quirk, but it only rarely occurs)
if(a[i][1] != 0 && a[i][0] != 0){
//output the x and y coords of the blob to the console
print(a[i][0] + " X " + a[i][1] + "\n");
//draw the exact point of the blob center
point(a[i][0],a[i][1]);
//draw an ellipse around the point to make it easyer to see
//you might also use it as bounds for tracking objects.
ellipse(a[i][0],a[i][1],20,20);
} else {
//(if the blob center was at 0x0)
//output to the console that this blob was skipped
print ("skipped. (0x0) \n");
}
}
// you might want to do more with the blob-centers...
//**********************************//
//draw bounding boxes of blobs
//(commented because it is merely illustrative)
// DO NOT USE THIS, JMYRON STILL HAS BUGS
// IN THE BOUNDING BOX ENUMERATION!
/*
a = m.globBoxes();
stroke(255,0,0);
for(int i=0;i<a.length;i++){
int[] b = a[i];
rect(b[0], b[1], b[2], b[3]);
}
*/
//draw edge pixels of blobs (this and the next chunks of code are processor-hogs)
//fetch all glob pixels from JMyron
int list[][][] = m.globPixels();
//set the stroke colour and weight
stroke(10,255,10);
strokeWeight(2);
//itterate through all glob pixels
for(int i=0;i<list.length;i++){
//fetch a "list" of pixels for each glob
int[][] pixellist = list[i];
//if the list is not empty
if(pixellist!=null){
//draw a vertex that runs through every single pixel in the "pixel list"
beginShape(POINTS);
for(int j=0;j<pixellist.length;j++){
vertex( pixellist[j][0] , pixellist[j][1] );
// print( pixellist[j][0] +" " + pixellist[j][1] );
}
endShape();
}
}
//return the stroke weight back to 1
strokeWeight(1);
//the following lines of codes draw quads
//i have commented them, because they are processor intensive
//and i can't think of any use for them yet.
/*
//draw quads - like bounding box, but a 4-pointed polygon.
(commented for being a processor-hog and i'm not finding anything interested to do with them)
a = m.globQuads(50,51);
stroke(0,0,100);
for(int i=0;i<a.length;i++){
int[] b = a[i];
quad(b[0], b[1],
b[2], b[3],
b[4], b[5],
b[6], b[7]);
}
*/
}
/**
*control events for the P5 interface elements.
**/
void controlEvent(ControlEvent theEvent) {
//if a control event is received from the P5 controller
println("got a control event from controller with id "+theEvent.controller().id());
//check from what controller it came
//by looking for the ID element
switch(theEvent.controller().id()) {
//if the ID element is number 1 (the tracing color slider)
case(1):
//set the tracecolor to the value from the slider
tracecolor = (int)(theEvent.controller().value());
print("tracecolor changed to " + tracecolor + "\n");
//end the switch-case
break;
case(2):
tracetolerance = (int)(theEvent.controller().value());
print("tracetolerance changed to " + tracetolerance + "\n");
break;
case(3):
//show the JMyron settings dialog
m.settings();
break;
}
}
/**
*if the sketch stops
**/
public void stop(){
//stop the jmyron object to release the camera
m.stop();
//then stop the runtime.
super.stop();
}