import processing.video.*; //on linux: sudo apt-get install libgstreamer-plugins-base0.10-dev libgstreamer0.10-dev libglib2.0-dev // sudo apt-get install gstreamer0.10-plugins-good import processing.serial.*; Serial sPort; Capture cam; PImage cam_reference; PImage cam_currentbox; PGraphics canvas; int currentID=0; //int MAXID = 50; //inclusive int MAXID = 9; int searchstate=0; //0=get reference image and ping box, 1=wait, 2=get image to compare and turn box off, 3=wait long starttime_wait=0; boolean running=false; color testcolor=color(255,255,255); color offcolor=color(0,0,0); color successcolor=color(0,255,0); color failcolor=color(255,0,0); static int boxnum=19; //how many boxes are visible? ArrayList boxes=new ArrayList(); //result will be written to the following arrays //int boxid[] = new int[boxnum]; //for found boxes //PVector boxpos[] = new PVector[boxnum]; //center position of box //PVector boxsize[] = new PVector[boxnum]; //size of box (width,height) //Settings //int FINDBOXES_MINIMUMBRIGHTNESS; //brightness difference required int FINDBOXES_MAXIMUMPIXELDISTANCE; //distance to add pixel to existing box PVector MINBOXSIZE; //minimum box size to accept box int TIME_FIND = 500; //time in ms to find box in image int TIME_RESULT = 250; //time in ms to show success/fail int TIME_TURNOFF = 250; //time in ms to wait to turn off float MINBRIGHTNESS_PERCENTILE=0.98; //percentile for minbrightness calculation (how many pixels will be considered). between 0(all) and 1(none). 0=all pixels. ->1=only bright pixels int MINIMUMALLOWEDBRIGHTNESS=50; //minimum brightness. will be limited to this lower bound if no box in image (percentile calculation yields low value) void setup() { size(640, 480); frameRate(30); String portName = Serial.list()[0]; sPort = new Serial(this, portName, 115200); canvas = createGraphics(width, height); //FINDBOXES_MINIMUMBRIGHTNESS=60; //brightness difference required FINDBOXES_MAXIMUMPIXELDISTANCE=width/200; //distance to add pixel to existing box MINBOXSIZE = new PVector(width/300,width/300); //minimum box size to accept box String[] cameras = Capture.list(); if (cameras.length == 0) { println("There are no cameras available for capture."); exit(); } else { println("Available cameras:"); for (int i = 0; i < cameras.length; i++) { println(i+"->"+cameras[i]); } // The camera can be initialized directly using an // element from the array returned by list(): //cam = new Capture(this, cameras[1]); //windows cam = new Capture(this, cameras[1]); //linux cam.start(); } cam_reference=cam.copy(); } void draw() { if (cam.available() == true) { cam.read(); } //image(cam, 0, 0); // The following does the same, and is faster when just drawing the image // without any additional resizing, transformations, or tint. //set(0, 0, cam); //Subtract images canvas.beginDraw(); canvas.background(0); canvas.blendMode(NORMAL); canvas.image(cam, 0, 0); canvas.blendMode(SUBTRACT); canvas.image(cam_reference, 0, 0); canvas.endDraw(); image(canvas,0,0); //show camera image if (running) { checkState(); } textSize(12); fill(0,255,150); //textcolor text("id: " + currentID, 10, 20); text("state: " + searchstate, 10, 20*2); //draw boxes for (Box box : boxes) { PVector boxcenter = box.getBoxCenter(); PVector boxsize = box.getBoxSize(); rectMode(CENTER); noFill(); fill(255,255,0,100); stroke(255,0,0); rect(boxcenter.x,boxcenter.y, boxsize.x,boxsize.y); textSize(12); fill(0,255,150); //textcolor text(box.getBoxID(), boxcenter.x,boxcenter.y); } } void checkState() { switch(searchstate) { case 0: //0=get reference image and ping box cam_reference=cam.copy(); println("Searching BoxID "+str(currentID)); colorBox(currentID,testcolor); starttime_wait=millis(); searchstate++; break; case 1: //1=wait if (millis()>starttime_wait + TIME_FIND) { //wait some time searchstate++; } break; case 2: //2=get image to compare and turn box off cam_currentbox=canvas.copy(); Box box = findSingleBox(cam_currentbox); //find single box in this image if (box!=null && (box.getBoxSize().x= pow(cam_currentbox.width/40,2)) { //if box is big enough box.setBoxID(currentID); boxes.add(box); } } if (box!=null) { println("Found box"); println("Pos: "+box.getBoxCenter().x+", "+box.getBoxCenter().y+" | size: "+box.getBoxSize().x+", "+box.getBoxSize().y); colorBox(currentID, successcolor); }else { println("No Box Found!"); colorBox(currentID, failcolor); } starttime_wait=millis(); searchstate++; break; case 3: //3=wait, color box fail or success if (millis()>starttime_wait + TIME_RESULT) { //wait some time colorBox(currentID,offcolor); //turn box off starttime_wait=millis(); searchstate++; } break; case 4: //wait for box to turn off completely if (millis()>starttime_wait + TIME_TURNOFF) { //wait some time starttime_wait=millis(); searchstate++; } break; case 5: //next box searchstate=0; currentID++; if (currentID>MAXID) { running=false; } break; } } void keyPressed() { if (key == 'n' ){ cam_reference=cam.copy(); println("New Reference Set"); } else if (key == 's' ){ running=true; colorAllOff(); //turn box off currentID=0; //reset searchstate=0; boxes.clear(); //reset found boxes println("Search started"); } } int getPercentileBrightness(PImage img, float percentile) { //percentile between 0 and 1 println("percentile="+str(percentile)); percentile=min(max(percentile,0.0),1.0); //limit to 0 to 1 int[] brightness=new int[img.pixels.length]; for (int i=0;i findBoxes(PImage img) { ArrayList foundboxes=new ArrayList(); int minimumbrightness=getPercentileBrightness(img, MINBRIGHTNESS_PERCENTILE); //calculate brightness by percentile based on minimum box size minimumbrightness=max(minimumbrightness, MINIMUMALLOWEDBRIGHTNESS); //limit lower value println(" minimumbrightness="+minimumbrightness); for (int y=0;yminimumbrightness) { //pixel has changed Box nearestBox=null; float nearestBoxDistance=MAX_FLOAT; for (Box cb : foundboxes) { //check all known boxes float cdist = cb.getDistanceTo(new PVector(x,y)); if (cdist<=FINDBOXES_MAXIMUMPIXELDISTANCE && cdist