package edu.hawaii.jmotif.performance.digits.processor1; import java.awt.image.BufferedImage; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.imageio.ImageIO; public class TestCropper { // data locations private static final String TEST_DATA = "data/digits/test.csv"; private static final DecimalFormat myFormatter = new DecimalFormat("000000"); private static final int THRESHOLD = 10; private static final String OUT_PREFIX = "data/digits/test/"; private static final Object SPACE = " "; /** * Runnable. * * @throws Exception if error occurs. */ public static void main(String[] args) throws Exception { // Map<String, double[]> trainData = readTrainData(TRAINING_DATA); List<double[]> testData = readTestData(TEST_DATA); BufferedWriter bw = new BufferedWriter(new FileWriter(new File(OUT_PREFIX + "metadata.csv"))); // for (Entry<String, double[]> e : trainData.entrySet()) { int counter = 0; int minWidth = 1000; String minwidthName = ""; for (double[] e : testData) { // System.out.println(e.getKey() + ": " + Arrays.toString(e.getValue())); // if (e.getKey().equalsIgnoreCase("1_87")) { // System.out.println(Arrays.toString(e.getValue())); // } // matrix int[][] mat = new int[28][28]; for (int i = 0; i < e.length; i++) { int row = i / 28; int col = i % 28; int value = (int) e[i]; if (value > THRESHOLD) { mat[row][col] = (int) e[i]; } else { mat[row][col] = 0; } } // write // BufferedImage img = new BufferedImage(28, 28, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < 28; ++x) { for (int y = 0; y < 28; ++y) { int grayscale = mat[y][x]; int colorValue = grayscale | grayscale << 8 | grayscale << 16; img.setRGB(x, y, colorValue); } } ImageIO.write(img, "png", new File("output_raw.png")); // get it cropped int[] cols = new int[28]; int[] rows = new int[28]; for (int i = 0; i < 28; i++) { for (int j = 0; j < 28; j++) { if (mat[i][j] > 0) { rows[i] = 1; cols[j] = 1; } } } // regions by x and y List<Interval> regionsX = getRegions(cols); List<Interval> regionsY = getRegions(rows); // get those with single intervals separated if (regionsX.size() == 1 && regionsY.size() == 1) { int ystart = regionsY.get(0).getStart(); int yend = regionsY.get(0).getEnd(); int xstart = regionsX.get(0).getStart(); int xend = regionsX.get(0).getEnd(); int croppedRows = yend - ystart + 1; int croppedCols = xend - xstart + 1; int[][] crop = new int[croppedRows][croppedCols]; for (int i = 0; i < croppedRows; i++) { for (int j = 0; j < croppedCols; j++) { crop[i][j] = mat[i + ystart][j + xstart]; } } // write // img = new BufferedImage(croppedCols, croppedRows, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < croppedCols; ++x) { for (int y = 0; y < croppedRows; ++y) { int grayscale = crop[y][x]; int colorValue = grayscale | grayscale << 8 | grayscale << 16; img.setRGB(x, y, colorValue); } } ImageIO.write(img, "png", new File("data/digits/test/" + myFormatter.format(counter) + "_cropped.png")); bw.write(myFormatter.format(counter) + " " + toMetadata(crop) + "\n"); } else { // sort by size Collections.sort(regionsX, new Comparator<Interval>() { @Override public int compare(Interval arg0, Interval arg1) { return Integer.valueOf(arg0.length()).compareTo(Integer.valueOf(arg1.length())); } }); Collections.sort(regionsY, new Comparator<Interval>() { @Override public int compare(Interval arg0, Interval arg1) { return Integer.valueOf(arg0.length()).compareTo(Integer.valueOf(arg1.length())); } }); // remove those tiny pixel ones while (regionsX.size() > 1 && regionsX.get(0).length() < 5) { // get the size of a feature here by Y int minY = 27; int maxY = 0; for (int i = 0; i < 28; i++) { for (int j = 0; j < regionsX.get(0).length(); j++) { if (mat[i][regionsX.get(0).getStart() + j] == 1) { if (i < minY) { minY = i; } if (i > maxY) { maxY = i; } } } } if ((maxY - minY) < 8) { regionsX.remove(0); } } while (regionsY.size() > 1 && regionsY.get(0).length() < 5) { // get the size of a feature here by X int minX = 27; int maxX = 0; for (int i = 0; i < regionsY.get(0).length(); i++) { for (int j = 0; j < 28; j++) { if (mat[regionsY.get(0).getStart() + i][j] == 1) { if (j < minX) { minX = j; } if (j > maxX) { maxX = j; } } } } if ((maxX - minX) < 8) { regionsY.remove(0); } } // plot now, but first resort by start Collections.sort(regionsX, new Comparator<Interval>() { @Override public int compare(Interval arg0, Interval arg1) { return Integer.valueOf(arg0.getStart()).compareTo(Integer.valueOf(arg1.getStart())); } }); Collections.sort(regionsY, new Comparator<Interval>() { @Override public int compare(Interval arg0, Interval arg1) { return Integer.valueOf(arg0.getStart()).compareTo(Integer.valueOf(arg1.getStart())); } }); int ystart = regionsY.get(0).getStart(); int yend = regionsY.get(regionsY.size() - 1).getEnd(); int xstart = regionsX.get(0).getStart(); int xend = regionsX.get(regionsX.size() - 1).getEnd(); int croppedRows = yend - ystart + 1; int croppedCols = xend - xstart + 1; if (croppedRows < 0 || croppedCols < 0) { System.out.println("gotcha"); } if (croppedRows < 7) { ystart = ystart - 2; yend = yend + 2; croppedRows = yend - ystart + 1; if (minWidth > croppedRows) { minWidth = croppedRows; minwidthName = "data/digits/test/" + myFormatter.format(counter) + "_cropped.png"; } } int[][] crop = new int[croppedRows][croppedCols]; for (int i = 0; i < croppedRows; i++) { for (int j = 0; j < croppedCols; j++) { crop[i][j] = mat[i + ystart][j + xstart]; } } // write // img = new BufferedImage(croppedCols, croppedRows, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < croppedCols; ++x) { for (int y = 0; y < croppedRows; ++y) { int grayscale = crop[y][x]; int colorValue = grayscale | grayscale << 8 | grayscale << 16; img.setRGB(x, y, colorValue); } } ImageIO.write(img, "png", new File("data/digits/test/" + myFormatter.format(counter) + "_cropped.png")); bw.write(myFormatter.format(counter) + " " + toMetadata(crop) + "\n"); } counter++; } bw.close(); } private static List<Interval> getRegions(int[] rows) { List<Interval> res = new ArrayList<Interval>(); int oldI = 0; int oldVal = rows[oldI]; boolean isBackground = true; if (oldVal > 0) { isBackground = false; } for (int i = 1; i < rows.length; i++) { if (oldVal != rows[i]) { if (rows[i] == 0) { if (!(isBackground)) { res.add(new Interval(oldI, i)); } isBackground = true; } else { isBackground = false; oldI = i; } oldVal = rows[i]; } } // special case if (rows[rows.length - 1] == 1 && !(isBackground)) { res.add(new Interval(oldI, rows.length - 1)); } return res; } private static ArrayList<double[]> readTestData(String fileName) throws NumberFormatException, IOException { ArrayList<double[]> res = new ArrayList<double[]>(); BufferedReader br = new BufferedReader(new FileReader(new File(fileName))); String line = ""; while ((line = br.readLine()) != null) { if (line.trim().length() == 0) { continue; } String[] split = line.trim().split(",|\\s+"); double[] series = new double[split.length]; for (int i = 0; i < split.length; i++) { series[i] = Double.valueOf(split[i].trim()).doubleValue(); } res.add(series); } br.close(); return res; } private static String toMetadata(int[][] crop) { int meta1 = crop.length; int meta2 = crop[0].length; // three horizontal cuts List<Interval> horizontalCut1 = getRegions(Arrays.copyOf(crop[meta1 / 4], crop[meta1 / 4].length)); List<Interval> horizontalCut2 = getRegions(Arrays.copyOf(crop[(meta1 / 4) * 2], crop[(meta1 / 4) * 2].length)); List<Interval> horizontalCut3 = getRegions(Arrays.copyOf(crop[(meta1 / 4) * 3], crop[(meta1 / 4) * 3].length)); // three vertivcal cuts List<Interval> verticalCut1 = getRegions(extractCol(crop, meta2 / 4)); List<Interval> verticalCut2 = getRegions(extractCol(crop, (meta2 / 4) * 2)); List<Interval> verticalCut3 = getRegions(extractCol(crop, (meta2 / 4) * 3)); StringBuffer sb = new StringBuffer(); sb.append(meta1).append(SPACE).append(meta2).append(SPACE); sb.append(horizontalCut1.size()).append(SPACE).append(horizontalCut2.size()).append(SPACE) .append(horizontalCut3.size()).append(SPACE); sb.append(verticalCut1.size()).append(SPACE).append(verticalCut2.size()).append(SPACE) .append(verticalCut3.size()); return sb.toString(); } private static int[] extractCol(int[][] crop, int j) { int[] res = new int[crop.length]; for (int i = 0; i < crop.length; i++) { res[i] = crop[i][j]; } return res; } }