improve finding algorithm and add export

This commit is contained in:
interfisch 2019-10-04 13:28:42 +02:00
parent 4ccffe4636
commit c70575547f
1 changed files with 82 additions and 6 deletions

View File

@ -11,6 +11,8 @@ PImage cam_reference;
PImage cam_currentbox;
PGraphics canvas;
PImage image_clear;
int currentID=0;
//int MAXID = 50; //inclusive
@ -36,9 +38,9 @@ ArrayList<Box> boxes=new ArrayList<Box>();
//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
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)
@ -73,6 +75,7 @@ void setup() {
cam = new Capture(this, cameras[1]); //linux
cam.start();
}
image_clear=cam.copy();
cam_reference=cam.copy();
}
@ -126,6 +129,7 @@ void checkState() {
switch(searchstate) {
case 0: //0=get reference image and ping box
cam_reference=cam.copy();
println();
println("Searching BoxID "+str(currentID));
@ -147,6 +151,7 @@ void checkState() {
Box box = findSingleBox(cam_currentbox); //find single box in this image
if (box!=null && (box.getBoxSize().x<MINBOXSIZE.x || box.getBoxSize().y<MINBOXSIZE.y)) { //box too small
box=null;
println(" Box too small");
}
if (box!=null) { //if box found
PVector boxsize = box.getBoxSize();
@ -190,6 +195,7 @@ void checkState() {
currentID++;
if (currentID>MAXID) {
running=false;
cam_reference=image_clear; //show normal camera image
}
break;
}
@ -200,19 +206,24 @@ void keyPressed() {
cam_reference=cam.copy();
println("New Reference Set");
} else if (key == 's' ){
} 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') {
saveBoxConfig();
}
}
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<brightness.length;i++) {
@ -256,6 +267,30 @@ ArrayList<Box> findBoxes(PImage img) {
}
println(" findBoxes(): foundboxes.size="+foundboxes.size());
//merge overlapping boxes together
for (int i=0;i<foundboxes.size();i++) {
Box fbox = foundboxes.get(i);
if (fbox.getMarked()) { continue; } //skip if this box was marked
for (int i2=i+1;i2<foundboxes.size();i2++) {
Box fbox2 = foundboxes.get(i2);
if (fbox.getMarked()) { continue; } //skip if this box was marked
if (fbox2.isInside(fbox) && fbox.isInside(fbox2)) {
fbox.merge(fbox2); //add pixels to one box
fbox2.setMarked(true); //mark for deletion
}
}
}
for (int i=0;i<foundboxes.size();i++) { //remove marked boxes
Box fbox = foundboxes.get(i);
if (fbox.getMarked()) { //if marked
foundboxes.remove(fbox); //remove merged box
i--;
}
}
println(" after merge: foundboxes.size="+foundboxes.size());
return foundboxes;
}
@ -273,10 +308,17 @@ Box findSingleBox(PImage img) {
public class Box {
ArrayList<PVector> boxpixels;
int boxid;
boolean marked=false;
public Box() {
boxpixels = new ArrayList<PVector>();
}
public void setMarked(boolean pm) {
marked=pm;
}
public boolean getMarked() {
return marked;
}
public void addPixel(PVector newpix) {
boxpixels.add(newpix);
@ -327,7 +369,7 @@ public class Box {
return boxsize;
}
public PVector getBoxCenter(){ //returns widht and height as vector
public PVector getBoxCenter(){ //returns width and height as vector
PVector upperleft= new PVector(MAX_FLOAT,MAX_FLOAT); //min x and y
PVector lowerright= new PVector(0,0); //max x and y
for (PVector pbox : boxpixels) {
@ -344,6 +386,28 @@ public class Box {
public int getPixelNumber() {
return this.boxpixels.size();
}
public boolean isInside(Box pbox) {
int pixelsinside=0; //for counting pixels of pbox inside this box
PVector pboxsize=pbox.getBoxSize();
PVector pboxcenter=pbox.getBoxCenter();
float pboxX1 = pboxcenter.x-pboxsize.x/2;
float pboxX2 = pboxcenter.x+pboxsize.x/2;
float pboxY1 = pboxcenter.y-pboxsize.y/2;
float pboxY2 = pboxcenter.y+pboxsize.y/2;
for (PVector pix : boxpixels) {
if (pix.x>pboxX1 && pix.x<pboxX2 && pix.y>pboxY1 && pix.y<pboxY2) { //is inside
pixelsinside++;
}
}
return pixelsinside>0;
}
public void merge(Box mergebox) { //merge pixels from mergebox inside this box
boxpixels.addAll(mergebox.getPixels());
}
}
void colorBox(int id, color c)
@ -354,3 +418,15 @@ void colorAllOff()
{
sPort.write("A,0\n");
}
void saveBoxConfig(){
String[] boxconfig=new String[boxes.size()];
for (int i=0;i<boxes.size();i++) {
Box box=boxes.get(i);
PVector boxcenter=box.getBoxCenter();
PVector boxsize=box.getBoxSize();
boxconfig[i]=box.getBoxID()+";"+(boxcenter.x/cam.width)+";"+(boxcenter.y/cam.height)+";"+(boxsize.x/cam.width)+";"+(boxsize.y/cam.height);
}
saveStrings("boxconfig.txt", boxconfig);
println("saved");
}