/* Last edited on 2013-03-21 02:02:00 by stolfilocal */ 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.FloatImageLanczos; import minetto.utils.FloatImageSegment; import minetto.utils.FloatImagePaint; public class TestFloatImage { public static void main(String[] args) throws IOException { System.err.println("Greetings Globe!"); String test_image_name = args[0]; try { /* Get a {BufferedImage} for the tests: */ BufferedImage buf = ImageIO.read(new File("data/" + test_image_name + ".png")); // test_to_from_BufferedImage(buf); // test_write_png_and_gamma(); // test_lanczos(buf); // test_downsample_upsample(); // test_scale_to_height(buf); // test_pyramids(buf); test_segmentation(buf); // test_downsample_spectrum(); } catch (IOException e) { System.err.println("Gosh! Ghastly grievance!"); } } public static void test_to_from_BufferedImage(BufferedImage buf) throws java.io.IOException { System.err.println("Going! (Testing conversions to/from {BufferedImage})"); for (int nc = 1; nc <= 4; nc++) { if (nc != 2) { System.err.println("Grooves = " + nc); FloatImage img = FloatImage.from_BufferedImage(buf, nc, (float)0.0, (float)1.0, 1.000); System.err.println("Genial!"); BufferedImage fub = FloatImage.to_BufferedImage(img, (float)0.0, (float)1.0, 1.000); System.err.println("Golly!"); File f = new File("out/from-buf-c" + nc + "-to-buf.png"); ImageIO.write(fub, "PNG", f); System.err.println("Gosh!"); } } } public static void test_write_png_and_gamma() { System.err.println("Going! (Testing {write_as_png} with some gammas)"); float dot_min = (float)0.25; float dot_max = (float)0.75; int n_dots = 11; FloatImage gam = FloatImage.make_gamma_test_image(n_dots, 47,31, dot_min, dot_max); System.err.println("Galumph!"); float umin = (float)0.0; float umax = (float)1.0; double[] gammas = new double[]{ 1.0000, 2.2000, 2.5000, 2.8000 }; for (int ig = 0; ig < gammas.length; ig++ ) { String fname = "out/test-gamma-g" + String.format("%6.4f",gammas[ig]) + ".png"; gam.write_as_png(fname, umin, umax, gammas[ig], true); System.err.println("Great! Gamma =" + String.format("%6.4f",gammas[ig])); } } // public static void test_lanczos(BufferedImage buf) { // System.err.println("Going! (Testing {FloatImageLanczos.{resize,resize_x,resize_y}})"); // int nc = 3; // FloatImage img = FloatImage.from_BufferedImage(buf, nc, (float)0.0, (float)1.0, 1.000); // for (int k = -2; k <= +2; k++) { // int nx_new = img.nx + k*10; String tagx = "-rx" + String.format("%04d",nx_new); // int ny_new = img.ny + k*10; String tagy = "-ry" + String.format("%04d",ny_new); // String fname = "out/test-lanczos"; // // FloatImage imgx = FloatImageLanczos.resize_x(img, nx_new); // imgx.write_as_png(fname + tagx, 0.0f, 1.0f, FloatImage.DEFAULT_GAMMA, true); // // FloatImage imgy = FloatImageLanczos.resize_y(img, ny_new); // imgy.write_as_png(fname + tagy, 0.0f, 1.0f, FloatImage.DEFAULT_GAMMA, true); // // FloatImage imgxy = FloatImageLanczos.resize(img, nx_new, ny_new); // imgxy.write_as_png(fname + tagx + tagy, 0.0f, 1.0f, FloatImage.DEFAULT_GAMMA, true); // } // System.err.println("Gonggg!"); // } public static void test_scale_to_height(BufferedImage buf) { System.err.println("Going! (Testing {FloatImage.scale_to_height})"); int nc = 3; FloatImage img = FloatImage.from_BufferedImage(buf, nc, (float)0.0, (float)1.0, 1.000); String fname = "out/test-scale"; for (int k = -2; k <= +2; k++) { int ny_new = img.ny + k*10; String tagy = "-sy" + String.format("%04d",ny_new); int nx_mod = 4; FloatImage imgy = img.scale_to_height(ny_new, nx_mod); System.err.printf(" original %d x %d resized %d x %d\n", img.nx, img.ny, imgy.nx, imgy.ny); imgy.write_as_png(fname + tagy, 0.0f, 1.0f, FloatImage.DEFAULT_GAMMA, true); assert((imgy.nx % nx_mod) == 0); } System.err.println("Gonggg!"); } public static void test_downsample_upsample() { System.err.println("Going! (Testing color ramps with various channels and {downsample,upsample})"); double gamma = 1.0000; for (int nc = 1; nc <= 4; nc++) { if (nc != 2) { System.err.println("Grooves = " + nc); float rmin = (float)-3.0; float rmax = (float)+3.0; FloatImage ram = FloatImage.make_ramps(nc,255,64, rmin, rmax); // FloatImage ram = FloatImage.make_ramps(nc,12,8, rmin, rmax); ram.write_as_png("out/ramps-c" + nc + ".png", rmin, rmax, gamma, true); int dn_order = 5; System.err.println("Goodness!"); FloatImage red = FloatImage.downsample(ram, dn_order, null, null); red.write_as_png("out/ramps-c" + nc + "-red.png", rmin, rmax, gamma, true); System.err.println("God Gracious!"); int up_order = dn_order; FloatImage mag = FloatImage.upsample(red, ram.nx, ram.ny, up_order); mag.write_as_png("out/ramps-c" + nc + "-red-mag.png", rmin, rmax, gamma, true); System.err.println("Gee!"); } } } public static void test_pyramids(BufferedImage buf) { System.err.println("Going! (Testing image pyramids and normalization)"); for (int nc = 1; nc <= 4; nc++) { if (nc != 2) { FloatImage.set_debug_prefix("out/img_pyr_c" + nc); FloatImage img = FloatImage.from_BufferedImage(buf, nc, (float)0.0, (float)1.0, 1.000); int max_levels = 10; int dn_order = 5; FloatImage[] avg_pyr = FloatImage.build_avg_pyramid(img, max_levels, dn_order); System.err.println("Giggles!"); float vqt = (float)((1.0/12.0)/(256*256)); /* Quantization noise variance for 256 levels. */ float[] noise_var = new float[nc]; Arrays.fill(noise_var, vqt); FloatImage[] var_pyr = FloatImage.build_var_pyramid(avg_pyr, noise_var, dn_order); System.err.println("Game!"); /* Create the blurred pyramids: */ int up_order = dn_order; int blur_step = 3; FloatImage[] avg_blr_pyr = FloatImage.build_blurred_pyramid(avg_pyr, blur_step, up_order, "avg"); System.err.println("Gorgeous!"); FloatImage[] var_blr_pyr = FloatImage.build_blurred_pyramid(var_pyr, blur_step, up_order, "var"); System.err.println("Gigantic!"); FloatImage[] nor_pyr = FloatImage.build_normalized_pyramid(avg_pyr, avg_blr_pyr, var_blr_pyr); System.err.println("Gracias!"); } } } public static void test_segmentation(BufferedImage buf) { System.err.println("Going! (Testing thresholding and segmentation)"); FloatImage.set_debug_prefix(null); /* Pyramid parameters: */ int max_levels = 4; int blur_step = 3; int dn_order = 3; int up_order = 6; double vcut_abs = -0.05; /* Cut level for binarization. */ /* Build a pyramid {rgb_pyr} of plain RGB images: */ FloatImage rgb = FloatImage.from_BufferedImage(buf, 3, (float)0.0, (float)1.0, 1.000); FloatImage[] rgb_pyr = FloatImage.build_avg_pyramid(rgb, max_levels + blur_step, dn_order); /* Build a pyramid {gry_pyr} of luminance images: */ FloatImage gry = FloatImage.from_BufferedImage(buf, 1, (float)0.0, (float)1.0, 1.000); FloatImage[] gry_pyr = FloatImage.build_avg_pyramid(gry, max_levels + blur_step, dn_order); /* Build a pyramid {var_pyr} of variance images for {gry_pyr}: */ float vqt = (float)((1.0/12.0)/(256*256)); /* Quantization noise variance for 256 levels. */ float[] noise_var = new float[gry.nc]; Arrays.fill(noise_var, vqt); FloatImage[] var_pyr = FloatImage.build_var_pyramid(gry_pyr, noise_var, dn_order); /* Build blurred versions of {gry_pyr,var_pyr}: */ FloatImage[] gry_blr_pyr = FloatImage.build_blurred_pyramid(gry_pyr, blur_step, up_order, "avg"); FloatImage[] var_blr_pyr = FloatImage.build_blurred_pyramid(var_pyr, blur_step, up_order, "var"); /* Build a contrast and brightness normalized pyramid {nor_pyr}: */ FloatImage[] nor_pyr = FloatImage.build_normalized_pyramid(gry_pyr, gry_blr_pyr, var_blr_pyr); FloatImage.set_debug_prefix("out/img_seg_c" + rgb.nc); FloatImage.debug_pyramid_image(rgb, 0.0f, 1.0f, 1.0f, "img_raw", 00); for (int level = 0; level < nor_pyr.length; level++) { /* Show the normalized image, sign-colorized: */ FloatImage nor_clr = nor_pyr[level].sign_colorize(-3.0f, 00.0f, +3.0f); FloatImage.debug_pyramid_image(nor_clr, 0.0f, 1.0f, 1.0f, "lum_nor", level); for (int sense = 0; sense < 2; sense++) { /* Threshold the level: */ FloatImage thr = nor_pyr[level].copy(); float vcut = (float)(vcut_abs * (1 - 2*sense)); float vmin = (float)(1 - sense); float vmax = (float)sense; float blur = 0.1f; thr.threshold(0,3, vcut, vmin,vmax, blur); FloatImage.debug_pyramid_image(thr, 0.0f, 1.0f, 1.0f, "lum_th" + sense, level); System.err.println("Greatmanitou!"); /* Segment the thresholded image: */ double rmin = 3; double rmax = 60; double fmin = 0.05; FloatImageSegment[] seg = FloatImageSegment.get_segments(thr, 1.0e-5, rmin, rmax, fmin); System.err.println("Gully! (found " + seg.length + " segments)"); int nx = gry_pyr[level].nx; int ny = gry_pyr[level].ny; /* Make a mask image for the segments: */ float[][] seg_rgb = pick_segment_colors(seg.length); FloatImage msg = FloatImageSegment.segments_to_image(seg, -2, nx+2, -2, ny+2, 3, seg_rgb, null); FloatImage.debug_pyramid_image(msg, 0.0f, 1.0f, 1.0f, "msk_sg" + sense, level); System.err.println("Geronimo!"); /* Extract segments from the original RGB image: */ FloatImage isg = FloatImageSegment.segments_to_image(seg, 0, nx, 0, ny, 0, null, rgb_pyr[level]); draw_segment_boxes(seg, seg_rgb, isg); FloatImage.debug_pyramid_image(isg, 0.0f, 1.0f, 1.0f, "rgb_sg" + sense, level); System.err.println("Gozado!"); } } } /* ---------------------------------------------------------------------- Draws the bounding boxes of the segments in {seg} onto {img} cycling the colors of {rgb}. */ private static void draw_segment_boxes(FloatImageSegment[] seg, float[][] rgb, FloatImage img) { if (rgb != null) { assert(rgb.length > 0); } for (int i = 0; i < seg.length; i++) { FloatImageSegment segi = seg[i]; int[][] box = segi.box(); double xmin = box[0][0]; double xmax = box[0][1]; double ymin = box[1][0]; double ymax = box[1][1]; FloatImagePaint.paint_rectangle(img, xmin, xmax, ymin, ymax, 1, rgb[i % rgb.length]); } } private static float[][] rainbow = new float[][] { { 1.000f, 0.0000f, 0.0000f, 1.0000f }, { 0.800f, 0.2000f, 0.0000f, 1.0000f }, { 0.300f, 0.6000f, 0.0000f, 1.0000f }, { 0.000f, 0.7000f, 0.0000f, 1.0000f }, { 0.000f, 0.7000f, 0.7000f, 1.0000f }, { 0.200f, 0.6000f, 1.0000f, 1.0000f }, { 0.700f, 0.1000f, 1.0000f, 1.0000f }, { 1.000f, 0.0000f, 0.5000f, 1.0000f }, { 0.500f, 0.5000f, 0.0000f, 1.0000f }, { 0.000f, 1.0000f, 0.0000f, 1.0000f } }; /* ---------------------------------------------------------------------- Choose a rainbow of colors for {ns} segments. */ private static float[][] pick_segment_colors(int ns) { return rainbow; } public static void test_downsample_spectrum() { System.err.println("Going! (Testing spectrum of downsampled images)"); int max_rounds = 6; int max_filter_size = 6; int nxy_target = 128; /* Size of final images is {nxy_target} or {nxy_target - 1}. */ for (int nw = 1; nw <= max_filter_size; nw++) { int nxy = nxy_target; for (int rounds = 0; rounds <= max_rounds; rounds++) { /* Create an image of size {nxy}, fill with unif randoms: */ Random buzz = new Random(46154615L + nxy); FloatImage img = new FloatImage(1, nxy, nxy); for (int y = 0; y < nxy; y ++) { for (int x = 0; x < nxy; x++) { img.set_sample(0,x,y, buzz.nextFloat()); } } System.err.println("Generated! nxy = " + img.nx + " x " + img.ny); /* Reduce it {rounds} times with {downsample}: */ for (int ir = 0; ir < rounds; ir++) { assert((img.nx % 2) == (nw % 2)); assert((img.ny % 2) == (nw % 2)); img = FloatImage.downsample(img, nw, null, null); System.err.println("Gleaned! size = " + img.nx + " x " + img.ny); } /* Write it to disk: */ float[] vrange = img.expand_or_crop(img.nx-8,img.ny-8,0.5,0.5,0.5f).get_sample_range(0,0); double vmag = Math.max(0.5-vrange[0], vrange[1]-0.5); double umag = Math.pow(Math.log(vmag),2); System.err.println("rangeplot: " + nw + " " + rounds + " " + String.format("%8.6f",vmag) + " " + String.format("%8.6f",umag)); float vmin = (float)(0.5 - 1.1*vmag); float vmax = (float)(0.5 + 1.1*vmag); String fname = "out/noise-dn-w" + String.format("%02d", nw) + "-r" + String.format("%02d", rounds); img.write_as_png(fname, vmin, vmax, 1.0000, true); img = null; /* Update {nxy} to get the correct final size with one more round: */ nxy = ((nw % 2) == 0 ? 2*nxy : 2*nxy - 1); } System.err.println("rangeplot: "); } } }