// Last edited on 2013-01-07 16:22:32 by stolfilocal package main; import JKernelMachines.Classifier; import java.awt.Dimension; import java.awt.Point; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Stack; import javax.imageio.ImageIO; import kruskal.Edge; import kruskal.Graph; import kruskal.Kruskal; import Segmentation.Toggle; import Segmentation.niblack; import structures.labels; import structures.struct_grow; import structures.struct_label; import thog.thog_desc; import utils.classifier_functions; import utils.comparator; import utils.file_functions; import utils.image_functions; import utils.FloatImage; import utils.labeling; import xml.fields; import xml.register; public class detection { public static void main(String[] args) throws IOException { String image_file_name = args[0]; double threshold = Double.parseDouble(args[1]); String thog_classifier_file_name = args[2]; String thog_params_file_name = args[3]; String output_image_file_name = args[4]; String debug_prefix = "debug/"; /* T-HOG descriptor extractor: */ thog_desc thog = new thog_desc (thog_params_file_name); /*window size of the thog sliding window detection*/ int window_y = thog.new_height; int window_x = window_y * 3; /* Get the input image: */ BufferedImage in_buf_image = ImageIO.read(new File(image_file_name)); FloatImage img = FloatImage.from_BufferedImage (in_buf_image, 1, 0.0f, 1.0f, FloatImage.DEFAULT_GAMMA); /* Build the normalized pyramid: */ int filter_size = 5; FloatImage pyr[] = create_normalized_pyramid(img, filter_size, debug_prefix); /* Find the max useful level: */ int n_levels = pyr.length; while ((n_levels > 0) && ((pyr[n_levels-1].nx < window_x) || (pyr[n_levels-1].ny < window_y))) { n_levels--; } System.err.printf("Number of levels used: %d\n", n_levels); /* T-HOG classifier - must be trained also with random background regions! */ Classifier trained_cls = classifier_functions.get_classifier (thog_classifier_file_name); FloatImage map = null; /* Collected result from all levels. */ for (int level = n_levels - 1; level >= 0; level--) { FloatImage res = detect_single_scale(pyr[level], window_x, window_y, thog, trained_cls, debug_prefix); { float[] range = res.get_sample_range(0,0); res.write_as_png (output_image_file_name + "_res_v" + level, range[0], range[1], FloatImage.DEFAULT_GAMMA, true); } /* Accumulates the result: */ if (map != null) { map = FloatImage.upsample(map, pyr[level].nx, pyr[level].ny, filter_size); for (int y = 0; y < map.ny; y++) { for (int x = 0; x < map.nx; x++) { double res_v = res.get_sample(0, x, y); double map_v = map.get_sample(0, x, y); map.set_sample(0, x, y, (float)(res_v + map_v)); } } } else { map = res.copy(); } { float[] range = map.get_sample_range(0,0); map.write_as_png (output_image_file_name + "_map_v" + level, range[0], range[1], FloatImage.DEFAULT_GAMMA, true); } } } /* ---------------------------------------------------------------------- Returns a single-channel image {msk} where the value of each pixel is proportional to the score assigned by the T-HOG classifier in the neighborhood of that pixel. */ private static FloatImage detect_single_scale ( FloatImage img, int window_x, int window_y, thog_desc thog, Classifier trained_cls, String debug_prefix ) { assert((window_x % 2) == 1); assert((window_y % 2) == 1); int hwindow_x = window_x / 2; int hwindow_y = window_y / 2; int step_x = Math.min(window_x/4, 3*window_y/4); int step_y = window_y/2; /* Margins to skip: */ int start_x = ((img.nx % step_x) + step_x)/2; int start_y = ((img.ny % step_y) + step_y)/2; FloatImage res = new FloatImage(1, img.nx, img.ny); res.set_all_samples(0f); for (int cy = start_y; cy < img.ny; cy += step_y) { /* Adjust window half-height to fit in image: */ int hy = Math.min(Math.min(cy, img.ny - 1 - cy), hwindow_y); for (int cx = start_x; cx < img.nx; cx += step_x) { /* Adjust window half-width to fit in image: */ int hx = Math.min(Math.min(cx, img.nx - 1 - cx), hwindow_x); /* Extract window and evaluate: */ FloatImage region = img.get_sub_image (cx - hx, cy - hy, cx + hx, cy + hy); float val = (float)thog.score(region, trained_cls, false, debug_prefix); paint_window(res, cx, cy, hx, hy, val); } } return res; } /* ---------------------------------------------------------------------- Paint the window with center {cx,cy} and half-size {hx,hy} in {res} with {val}, with soft weight. */ public static void paint_window (FloatImage res, int cx, int cy, int hx, int hy, float val) { for (int dy = -hy; dy <= +hy; dy++) { double wy = (1 + Math.cos(Math.PI*dy/((double)hy + 0.5)))/2.0; for (int dx = -hx; dx <= +hx; dx++) { double wx = (1 + Math.cos(Math.PI*dx/((double)hx + 0.5)))/2.0; double weighted_val = wx*wy*val; double old_val = res.get_sample(0, cx+dx, cy+dy); res.set_sample(0, cx+dx, cy+dy, (float)(old_val + weighted_val)); } } } }