package structures; import java.util.LinkedList; public class struct_label { public int id; public int xmin; public int ymin; public int xmax; public int ymax; public int barx; public int bary; public int surf; public int level; public int regions; public double weight; public boolean active; public static struct_label copy (struct_label source) { struct_label target = new struct_label(); target.id = source.id; target.xmin = source.xmin; target.ymin = source.ymin; target.xmax = source.xmax; target.ymax = source.ymax; target.barx = source.barx; target.bary = source.bary; target.surf = source.surf; target.active = source.active; target.weight = source.weight; target.regions = source.regions; target.level = source.level; return target; } public static boolean similar (struct_label r, struct_label s, int level) { double threshold_wr = 8.0; double threshold_hr = 2.0; double threshold_dx = 2.0; double threshold_dy = 2.0; double[] d = similarity_metrics (r, s); assert(d.length == 4); if ( (d[0] < threshold_dx) && (d[1] < threshold_dy) && (d[2] < threshold_hr) && (d[3] < threshold_wr) ) { return true; } else { return false; } } public static double[] similarity_metrics (struct_label r, struct_label s) { double h1 = (r.ymax - r.ymin + 1); double w1 = (r.xmax - r.xmin + 1); double c1_x = (r.xmax + r.xmin)/2; double c1_y = (r.ymax + r.ymin)/2; double h2 = (s.ymax - s.ymin + 1); double w2 = (s.xmax - s.xmin + 1); double c2_x = (s.xmax + s.xmin)/2; double c2_y = (s.ymax + s.ymin)/2; double h_min = Math.min (h1, h2); double[] v = new double[4]; /*ratio dx/h_min - minimum is 1*/ v[0] = (Math.abs (Math.abs (c1_x - c2_x) - (w1 + w2)/2.0))/h_min + 1.0; /*ratio dy/h_min - minimum is 1*/ v[1] = (Math.abs(c1_y - c2_y))/h_min + 1.0; /*height ratio - minimum is 1*/ v[2] = Math.max(h1/h2, h2/h1); /*width ratio - minimum is 1*/ v[3] = Math.max(w1/w2, w2/w1); System.err.printf("v[0]: %f, v[1]: %f, v[2]: %f, v[3]: %f\n", v[0], v[1], v[2], v[3]); return v; } public static double compute_euclidean_similarity (double candidate[]) { double[] minimum = {1.0, 1.0, 1.0, 1.0}; assert(minimum.length == candidate.length); int size = minimum.length; double sum = 0.0; for (int i = 0; i < size/2; i++) { sum += (candidate[i] - minimum[i])*(candidate[i] - minimum[i]); } return Math.sqrt(sum); } public static boolean overlap2 (struct_label l1, struct_label l2, double threshold) { double area_l2 = area(l2); double area_l1 = area(l1); double area_overlap = overlap_area (l1, l2); System.err.printf("overlap: %f, area: %f, ratio: %f\n", area_overlap, area_l2, area_overlap/area_l2); if (((area_overlap/area_l2) > threshold) || ((area_overlap/area_l1) > threshold)) { return true; } return false; } public static void merge (struct_label l1, struct_label l2) { l1.xmin = Math.min(l1.xmin, l2.xmin); l1.xmax = Math.max(l1.xmax, l2.xmax); l1.ymin = Math.min(l1.ymin, l2.ymin); l1.ymax = Math.max(l1.ymax, l2.ymax); l1.regions++; } public static struct_label Merge (struct_label l1, struct_label l2) { struct_label n = new struct_label(); if (l1 != null) { n.xmin = Math.min(l1.xmin, l2.xmin); n.xmax = Math.max(l1.xmax, l2.xmax); n.ymin = Math.min(l1.ymin, l2.ymin); n.ymax = Math.max(l1.ymax, l2.ymax); n.regions = l1.regions++; n.id = l1.id; } else { n.xmin = l2.xmin; n.xmax = l2.xmax; n.ymin = l2.ymin; n.ymax = l2.ymax; n.regions = l2.regions; n.id = l2.id; } return n; } public static boolean merge (struct_label l1, struct_label l2, LinkedList list, boolean flag) { struct_label merge = new struct_label(); merge.xmin = Math.min(l1.xmin, l2.xmin); merge.xmax = Math.max(l1.xmax, l2.xmax); merge.ymin = Math.min(l1.ymin, l2.ymin); merge.ymax = Math.max(l1.ymax, l2.ymax); l1.xmin = merge.xmin; l1.xmax = merge.xmax; l1.ymin = merge.ymin; l1.ymax = merge.ymax; if (flag) { l1.regions++; } return true; } public static boolean overlap (struct_label l1, struct_label l2) { double threshold = 0.5; double area_l1 = area(l1); double area_l2 = area(l2); double area_overlap = overlap_area (l1, l2); if ( ((area_overlap/area_l1) > threshold) && ((area_overlap/area_l2) > threshold) ) { return true; } return false; } public static double overlap_area (struct_label l1, struct_label l2) { int xMin = Math.max(l1.xmin, l2.xmin); int xMax = Math.min(l1.xmax, l2.xmax); int yMin = Math.max(l1.ymin, l2.ymin); int yMax = Math.min(l1.ymax, l2.ymax); if ((yMin > yMax) || (xMin > xMax)) return 0.0; double overlap = area (xMin, yMin, xMax, yMax); return overlap; } public static int area (struct_label l) { return (l.xmax - l.xmin) * (l.ymax - l.ymin); } public static int area (int x1, int y1, int x2, int y2) { return (x2 - x1) * (y2 - y1); } }