package segmentation; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.util.ArrayList; import java.util.LinkedList; import javax.imageio.ImageIO; import preprocessing.Util; import regrouping.Box; public class Regions { final public int NOLEVEL = -1; private int x_min; private int y_min; private int x_max; private int y_max; private int xg; private int yg; private int low_valued_neighbour; private int high_valued_neighbour; private int surface; private double dec; private int level; /*Level of the pyramid where the box region was found or NOLEVEL*/ private double perimeter; private double moyenne_comp; private double moyenne_surf; private double moyenne_perim; private double moyenne_epais_max; private double moyenne_surf_surfconv; private double variance_surf_surfconv; private int h; private int w; public Regions (){ this.x_min = 0; this.y_min = 0; this.x_max = 0; this.y_max = 0; this.xg = 0; this.yg = 0; this.low_valued_neighbour = 0; this.high_valued_neighbour = 0; //this.perimeter = 0; this.surface = 0; this.dec = 0.0; this.level = NOLEVEL; } public int getH () { return this.h; } public void setH (int h) { this.h = h; } public int getW () { return this.w; } public void setW (int w) { this.w = w; } public double getMoyenneComp () { return this.moyenne_comp; } public double getMoyenneSurf () { return this.moyenne_surf; } public double getMoyennePerim () { return this.moyenne_perim; } public double getMoyenneEpaisMax () { return this.moyenne_epais_max; } public double getMoyenneSurfConv () { return this.moyenne_surf_surfconv; } public double getVarianceSurfConv () { return this.variance_surf_surfconv; } public void setMoyenneComp (double moyenne_comp) { this.moyenne_comp = moyenne_comp; } public void setMoyenneSurf (double moyenne_surf ) { this.moyenne_surf = moyenne_surf ; } public void setMoyennePerim (double moyenne_perim ) { this.moyenne_perim = moyenne_perim ; } public void setMoyenneEpaisMax (double moyenne_epais_max) { this.moyenne_epais_max = moyenne_epais_max; } public void setMoyenneSurfConv (double moyenne_surf_surfconv) { this.moyenne_surf_surfconv = moyenne_surf_surfconv; } public void setVarianceSurfConv (double variance_surf_surfconv ) { this.variance_surf_surfconv = variance_surf_surfconv ; } public void setXmin (int x_min) { this.x_min = x_min; } public int getXmin () { return this.x_min; } public void setYmin (int y_min) { this.y_min = y_min; } public int getYmin () { return this.y_min; } public void setLevel (int level) { this.level = level; } public int getLevel () { return this.level; } public void setXmax (int x_max) { this.x_max = x_max; } public int getXmax () { return this.x_max; } public void setYmax (int y_max) { this.y_max = y_max; } public int getYmax () { return this.y_max; } public void setPerimeter (double perimeter) { this.perimeter = perimeter; } public double getPerimeter () { return this.perimeter; } public void setLowValueNeighbour (int low_valued_neighbour) { this.low_valued_neighbour = low_valued_neighbour; } public int getLowValuedNeighbour () { return this.low_valued_neighbour; } public void setHighValueNeighbour (int high_valued_neighbour) { this.high_valued_neighbour = high_valued_neighbour; } public int getHighValuedNeighbour () { return this.high_valued_neighbour; } public int getXg () { return this.xg; } public void setXg (int xg) { this.xg = xg; } public int getYg () { return this.yg; } public void setYg (int yg) { this.yg = yg; } public int getSurface () { return this.surface; } public void setSurface (int surface) { this.surface = surface; } public void setDec (double dec) { this.dec = dec; } public double getDec () { return this.dec; } public void add_point_to_region (int x, int y) { this.x_min = Math.min (this.x_min, x); this.x_max = Math.max (this.x_max, x); this.y_min = Math.min (this.y_min, y); this.y_max = Math.max (this.y_max, y); this.xg += x; this.yg += y; this.surface++; } public static void rescale_size (Regions reg, int scale_old, int scale_new) { assert(scale_old >= scale_new); double mag = Math.pow(Math.sqrt(2.0),scale_old-scale_new); reg.setXmin((int)(reg.getXmin()*mag)); reg.setYmin((int)(reg.getYmin()*mag)); reg.setXmax((int)(reg.getXmax()*mag)); reg.setYmax((int)(reg.getYmax()*mag)); //reg.setXmax((reg.getXmax()+1)*mag-1); //reg.setYmax((reg.getYmax()+1)*mag-1); reg.setXg((int)(reg.getXg()*mag)); reg.setYg((int)(reg.getYg()*mag)); //reg.setPerimeter(reg.getPerimeter()*mag); reg.setSurface((int)(reg.getSurface()*(mag*mag))); reg.setDec(reg.getDec()); reg.setLowValueNeighbour(reg.getLowValuedNeighbour()); reg.setHighValueNeighbour(reg.getHighValuedNeighbour()); } /*Assuming that two boxes overlap, returns {true} iff the box {regi} is more likely to be letter than * box {regj}. Assumes that {dec} fields have been set. */ public static boolean dominates (Regions regi, Regions regj) { return (regi.getDec() < regj.getDec()); } /*Returns the area of intersection of two bounding boxes, divided by the area of the smallest box.*/ public static double overlap (Regions regi, Regions regj) { int regi_xmin = regi.getXmin (); int regi_xmax = regi.getXmax (); int regi_ymin = regi.getYmin (); int regi_ymax = regi.getYmax (); int regj_xmin = regj.getXmin (); int regj_xmax = regj.getXmax (); int regj_ymin = regj.getYmin (); int regj_ymax = regj.getYmax (); int ov_xmin = Math.max(regi_xmin, regj_xmin); int ov_xmax = Math.min(regi_xmax, regj_xmax); int ov_ymin = Math.max(regi_ymin, regj_ymin); int ov_ymax = Math.min(regi_ymax, regj_ymax); if (ov_xmin > ov_xmax || ov_ymin > ov_ymax) return 0; int regi_area = (regi_xmax - regi_xmin + 1)*(regi_ymax - regi_ymin + 1); int regj_area = (regj_xmax - regj_xmin + 1)*(regj_ymax - regj_ymin + 1); int ov_area = (ov_xmax - ov_xmin + 1)*(ov_ymax - ov_ymin + 1); int min_area = Math.min (regi_area, regj_area); return ((double)ov_area)/((double)min_area); } public static void show_list (LinkedList L, BufferedImage img, String image_name) { BufferedImage outimg = Util.imageScale (img, 1.0); Graphics2D gw = outimg.createGraphics(); gw.setStroke(new BasicStroke(2.5f)); gw.setColor(Color.white); Graphics2D gb = outimg.createGraphics(); gb.setStroke(new BasicStroke(2.5f)); gb.setColor(Color.black); for (int l = 0; l < L.size(); l++) { Box r = L.get(l); if(r.getDec() >= 0) { continue; } //divided by 2 because the boxes are relative to the bicubic intepolated image int x = (int)(r.getXMin()/2.0); int y = (int)(r.getYMin()/2.0); int w = (int)((r.getXMax() - r.getXMin() + 1)/2.0); int h = (int)((r.getYMax() - r.getYMin() + 1)/2.0); /*int x = r.getXMin(); int y = r.getYMin(); int w = (r.getXMax() - r.getXMin() + 1); int h = (r.getYMax() - r.getYMin() + 1);*/ gw.drawRect(x, y, w, h); gb.drawRect(x-3, y-3, w+6, h+6); //System.err.printf("Drawing reg[%d] = [%d,%d] x [%d,%d] \n", l, x, y, w, h); } gw.dispose(); gb.dispose(); try { ImageIO.write(outimg, "png", new File(image_name)); } catch (Exception e) { System.err.printf("cannot write image %s\n", image_name); } } public static void show_list (ArrayList L, BufferedImage img, String image_name) { BufferedImage outimg = Util.imageScale (img, 1.0); Graphics2D g = outimg.createGraphics(); g.setStroke(new BasicStroke(1.0f)); g.setColor(Color.red); for (int l = 0; l < L.size(); l++) { Regions r = L.get(l); //divided by 2 because the boxes are relative to the bicubic intepolated image int x = r.getXmin()/2; int y = r.getYmin()/2; int w = (r.getXmax() - r.getXmin() + 1)/2; int h = (r.getYmax() - r.getYmin() + 1)/2; g.drawRect(x, y, w, h); //System.err.printf("Drawing reg[%d] = [%d,%d] x [%d,%d] \n", l, x, y, w, h); } g.dispose(); try { ImageIO.write(outimg, "png", new File(image_name)); } catch (Exception e) { System.err.printf("cannot write image %s\n", image_name); } } public static void redefine_regions (ArrayList L) { for (int l = 0; l < L.size(); l++) { Regions r = L.get(l); //divided by 2 because the boxes are relative to the bicubic intepolated image r.setXmin((int)(r.getXmin()/2)); r.setYmin((int)(r.getYmin()/2)); r.setXmax((int)(r.getXmax()/2+1)); r.setYmax((int)(r.getYmax()/2+1)); r.setXg((int)(r.getXg()/2)); r.setYg((int)(r.getYg()/2)); r.setH((int)(r.getH()*2)); r.setW((int)(r.getW()*2)); r.setSurface(r.getH()*r.getW()); } } }