/* Last edited on 2013-03-18 20:15:49 by stolfilocal */ /* Reads a bilevel image. Writes to stdout the bounding boxes of the white areas. */ import java.lang.Math; import java.util.Arrays; import java.util.Random; import java.io.File; import java.io.IOException; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import minetto.utils.FloatImage; import minetto.utils.FloatImagePaint; import minetto.utils.FloatImageSegment; /* Segmentation of binary masks (e.g. reference files for segmentation algs.) Usage: "SegmentTruth.java {INDIR} {OUTDIR} {IMAGENAME}" Reads an image file "{INDIR}/{IMAGENAME}.png". Assumes it is a grayscale mask where 0 is background and 1 is a relevant segment. Calls {do_segment_truth} to identify the segments (disconnected white splotches) and write to standard output a text file in the format {IMAGENAME} {LEVEL} {ICH} {IWD} {XMIN} {YMIN} {W} {H} {RMIN} {RMAX} {VAL} where {LEVEL} is always "00" {ICH} and {WCH} are sequential segment numbers (from 0). {XMIN} {YMIN} {W} {H} is the segment's bounding box. {RMIN} {RMAX} are the min and max radii of the ellipse of inertia. {VAL} is always "?". Also writes to "{OUTDIR}/{IMAGENAME}-boxes.png" an image showing the bounding boxes outlined in colors. */ public class SegmentTruth { public static void main(String[] args) throws IOException { String in_dir = args[0]; String out_dir = args[1]; String image_name = args[2]; String fname_in = in_dir + "/" + image_name + ".png"; BufferedImage buf = null; try { buf = ImageIO.read(new File(fname_in)); } catch (IOException e) { System.err.println("Failure while reading image \"" + fname_in + "\""); } FloatImage img = do_segment_truth(buf, image_name); String fname_out = out_dir + "/" + image_name + "-boxes.png"; img.write_as_png(fname_out, 0.0f, 1.0f, 1.000, true); } /* ---------------------------------------------------------------------- /* Segments the image {buf} and writes to standard output the file described above. Omits segments that span the whole image. Returns an image with the segments outlined in various colors. */ public static FloatImage do_segment_truth(BufferedImage buf, String image_name) { FloatImage.set_debug_prefix(null); /* Pyramid parameters: */ int max_levels = 3; int blur_step = 3; int dn_order = 5; int up_order = 5; double vcut_abs = -0.05; /* Cut level for binarization. */ /* Convert to grayscale: */ FloatImage gry = FloatImage.from_BufferedImage(buf, 1, (float)0.0, (float)1.0, 1.000); /* Diagnostic image: */ FloatImage img = FloatImage.from_BufferedImage(buf, 3, (float)0.0, (float)1.0, 1.000); /* Find segments: */ double pmin = 0.5; double rmin = 1.0e-10; double rmax = 1.0e10; double fmin = 0.0; FloatImageSegment[] seg = FloatImageSegment.get_segments(gry, pmin, rmin, rmax, fmin); System.err.printf("found %d segments\n", seg.length); /* Write bbox file: */ int iseq = 0; for (int i = 0; i < seg.length; i++) { FloatImageSegment segi = seg[i]; int[][] box = segi.box(); int xmin = box[0][0]; int ymin = box[1][0]; int wx = box[0][1] - xmin + 1; int wy = box[1][1] - ymin + 1; if ((wx < gry.nx) && (wy < gry.ny)) { int level = 0; double[] radii = segi.radii(); double srmax = radii[0]; double srmin = radii[1]; String val = "?"; System.out.printf( "%30s %02d %5d %5d %5d %5d %5d %5d %7.1f %7.1f %s\n", image_name, level, iseq, iseq, xmin, ymin, wx, wy, srmin, srmax, val ); float color[] = new float[]{ (float)(0.6 + 0.4*Math.cos(2*Math.PI/6*((iseq + 0) % 6))), (float)(0.6 + 0.4*Math.cos(2*Math.PI/6*((iseq + 2) % 6))), (float)(0.6 + 0.4*Math.cos(2*Math.PI/6*((iseq + 4) % 6))) }; FloatImagePaint.paint_rectangle(img, xmin,xmin+wx, ymin,ymin+wy, 1, color); iseq = iseq + 1; } } System.out.flush(); return img; } }