From 7e4c5352b3df802845b2ca52425233729707a9da Mon Sep 17 00:00:00 2001 From: Fisch Date: Sun, 13 Dec 2020 01:13:17 +0100 Subject: [PATCH] chang kinect wuerfel configfinder to work with achterbahn --- .../autoconfigurator/autoconfigurator.pde | 605 ++++++++++++++++++ 1 file changed, 605 insertions(+) create mode 100644 achterbahnconfig/autoconfigurator/autoconfigurator.pde diff --git a/achterbahnconfig/autoconfigurator/autoconfigurator.pde b/achterbahnconfig/autoconfigurator/autoconfigurator.pde new file mode 100644 index 0000000..5c5d9e3 --- /dev/null +++ b/achterbahnconfig/autoconfigurator/autoconfigurator.pde @@ -0,0 +1,605 @@ +import processing.video.*; //Video | GStreamer-based video library for Processing + +//on linux: sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libglib2.0-dev +// sudo apt-get install libgstreamer-plugins-good1.0-dev + +import processing.serial.*; +Serial sPort; + +Capture cam; + +PImage cam_reference; +PImage cam_currentbox; +PGraphics canvas; + +PImage image_clear; + + +int currentID=0; +//int MAXID = 50; //inclusive +//int MAXID = 599; +int MAXID = 10; +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; + +float PIXELDISTANCE_CM=1.6; //pixeldistance in centimeter + +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 = 100; //time in ms to find box in image +int TIME_RESULT = 100; //time in ms to show success/fail +int TIME_TURNOFF = 100; //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); + + /* + for (int i=0; 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[0]); //linux + cam.start(); + } + image_clear=cam.copy(); + 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 + + println("Set achterbahn to debug mode"); + String writeserial="debug_dark\n"; + sPort.write(writeserial); + delay(500); + + + cam_reference=cam.copy(); + println(); + println("Searching BoxID "+str(currentID)); + + + colorBox(currentID); + + 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); + box.setConfidence(1.0); + 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); + }else { + println("No Box Found!"); + //colorBox(currentID); + } + + starttime_wait=millis(); + searchstate++; + break; + + case 3: //3=wait, color box fail or success + if (millis()>starttime_wait + TIME_RESULT) { //wait some time + colorAllOff(); + 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; + cam_reference=image_clear; //show normal camera image + } + break; + } +} + +void keyPressed() { + if (key == 'n' ){ + cam_reference=cam.copy(); + println("New Reference Set"); + + } else if (key == 10){ //ENTER + running=true; + colorAllOff(); //turn box off + currentID=0; //reset + searchstate=0; + boxes.clear(); //reset found boxes + println("Search started"); + } else if (key == 'r' ){ + running=false; + cam_reference=image_clear; //show normal camera image + } else if(key == 's') { + sendHeights(); + } else if(key == 'S') { + saveToEEPROM(); + } else if(key == 'p') { + calculateConfidences(); + } + + + +} + +int getPercentileBrightness(PImage img, float percentile) { //percentile between 0 and 1 + 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 && cdist0.5) { + writeserial="setpx="+box.getBoxID()+","+int(pixelvalue)+"\n"; + sPort.write(writeserial); + } + } + println("send"); +} + +void calculateConfidences() { + for (int i=0;iboxes.get(prevBoxi).getBoxID()) { //new one closer to boxid + prevBoxi=j; + } + } + if (boxes.get(j).getBoxID()>boxid) { //found + if (nextBoxi<0 || boxes.get(j).getBoxID()=0) { + PVector prevboxcenter=boxes.get(prevBoxi).getBoxCenter(); + prevdist=dist(prevboxcenter.x,prevboxcenter.y,boxcenter.x,boxcenter.y); + int boxsteps = boxid-boxes.get(prevBoxi).getBoxID(); //1 if previous box found. greater if boxes missing in between + prevdist*=boxsteps; + } + float nextdist=0; + if (nextBoxi>=0) { + PVector nextboxcenter=boxes.get(nextBoxi).getBoxCenter(); + nextdist=dist(nextboxcenter.x,nextboxcenter.y,boxcenter.x,boxcenter.y); + int boxsteps = boxes.get(nextBoxi).getBoxID()-boxid; //1 if previous box found. greater if boxes missing in between + prevdist*=boxsteps; + } + float maxdist=max(prevdist,nextdist); //maximum distance to neighbor if one exists + maxdist/=cam.width; + + float confidence=constrain(map(maxdist, 0.05, 0.5, 1.0,0.1), 0.1,1.0); + + + confidence*=constrain(map(boxarea, 1000, 10000, 1.0,0.5), 0.5,1.0); + + box.setConfidence(confidence); + println(boxid+":"+"maxdist="+maxdist+", area="+boxarea+", confidence="+confidence); + } +} + +float getMeanDist() { //run after confidences have been calculated + float meandist=0; + int meancount=0; + for (int i=0;i0.5) { //confidence high enough + int boxid=box.getBoxID(); + PVector boxcenter=box.getBoxCenter(); + PVector boxsize=box.getBoxSize(); + + //calculate distance to neighboring boxes + int prevBoxi=-1; + int nextBoxi=-1; + for (int j=0;jboxes.get(prevBoxi).getBoxID()) { //new one closer to boxid + prevBoxi=j; + } + } + if (boxes.get(j).getBoxID()>boxid) { //found + if (nextBoxi<0 || boxes.get(j).getBoxID()=0) { + PVector prevboxcenter=boxes.get(prevBoxi).getBoxCenter(); + prevdist=dist(prevboxcenter.x,prevboxcenter.y,boxcenter.x,boxcenter.y); + int boxsteps = boxid-boxes.get(prevBoxi).getBoxID(); //1 if previous box found. greater if boxes missing in between + prevdist*=boxsteps; + } + float nextdist=0; + if (nextBoxi>=0) { + PVector nextboxcenter=boxes.get(nextBoxi).getBoxCenter(); + nextdist=dist(nextboxcenter.x,nextboxcenter.y,boxcenter.x,boxcenter.y); + int boxsteps = boxes.get(nextBoxi).getBoxID()-boxid; //1 if previous box found. greater if boxes missing in between + prevdist*=boxsteps; + } + mindist=max(prevdist,nextdist); //maximum distance to neighbor if one exists + } + + if (mindist>0){ + meancount++; + meandist+=mindist; + } + + } //end for all boxes + return meandist/meancount; +} + +void saveToEEPROM() { + String writeserial="save\n"; + sPort.write(writeserial); + delay(500); + println("send save to eeprom"); +}