From 53d6fc3664be641866feef4a6de91a22b23c4cd4 Mon Sep 17 00:00:00 2001 From: interfisch Date: Fri, 4 Oct 2019 12:10:42 +0200 Subject: [PATCH] add working webcam boxfinder --- configfinder/configfinder.pde | 356 ++++++++++++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100644 configfinder/configfinder.pde diff --git a/configfinder/configfinder.pde b/configfinder/configfinder.pde new file mode 100644 index 0000000..9db9923 --- /dev/null +++ b/configfinder/configfinder.pde @@ -0,0 +1,356 @@ +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