package edu.berkeley.cs.nlp.ocular.data; import java.io.File; import java.io.FilenameFilter; import java.util.Arrays; import java.util.List; import edu.berkeley.cs.nlp.ocular.image.ImageUtils; import edu.berkeley.cs.nlp.ocular.image.ImageUtils.ConnectedComponentProcessor; import edu.berkeley.cs.nlp.ocular.image.ImageUtils.PixelType; import edu.berkeley.cs.nlp.ocular.preprocessing.Binarizer; import edu.berkeley.cs.nlp.ocular.preprocessing.LineExtractor; import tberg.murphy.arrays.a; import tberg.murphy.fileio.f; import tberg.murphy.threading.BetterThreader; public class FirstFolioRawImageLoader { public static class FirstFolioRawImageDocument implements Document { private final String baseName; final PixelType[][][] observations; public FirstFolioRawImageDocument(String inputPath, String baseName, int lineHeight, double binarizeThreshold) { this.baseName = baseName; double[][] levels = ImageUtils.getLevels(f.readImage(inputPath+"/"+baseName)); ConnectedComponentProcessor ccprocBig = new ConnectedComponentProcessor() { public void process(double[][] levels, List<int[]> connectedComponent) { if (connectedComponent.size() > 1000) { for (int[] pixel : connectedComponent) { levels[pixel[0]][pixel[1]] = 255.0; } } } }; ImageUtils.processConnectedComponents(levels, 50.0, ccprocBig); Binarizer.binarizeGlobal(binarizeThreshold, levels); ConnectedComponentProcessor ccprocSmall = new ConnectedComponentProcessor() { public void process(double[][] levels, List<int[]> connectedComponent) { if (connectedComponent.size() < 20 || connectedComponent.size() > 1000) { for (int[] pixel : connectedComponent) { levels[pixel[0]][pixel[1]] = 255.0; } } } }; ImageUtils.processConnectedComponents(levels, 127.0, ccprocSmall); int padHeight = 0; double[][] topPadLevels = new double[levels.length][]; for (int i=0; i<levels.length; ++i) topPadLevels[i] = a.append(a.add(a.zerosDouble(padHeight), 255.0), levels[i]); List<double[][]> lines = LineExtractor.extractLines(topPadLevels); observations = new PixelType[lines.size()][][]; for (int i=0; i<lines.size(); ++i) { if (lineHeight >= 0) { observations[i] = ImageUtils.getPixelTypes(ImageUtils.resampleImage(ImageUtils.makeImage(lines.get(i)), lineHeight)); } else { observations[i] = ImageUtils.getPixelTypes(ImageUtils.makeImage(lines.get(i))); } } } public PixelType[][][] loadLineImages() { return observations; } public String[][] loadDiplomaticTextLines() { return null; } public String[][] loadNormalizedTextLines() { return null; } public List<String> loadNormalizedText() { return null; } public String baseName() { return baseName; } } public static List<Document> loadDocuments(final String inputPath, final int lineHeight, final double binarizeThreshold, final int numThreads) { System.out.println("Extracting text line images from dataset "+inputPath); File dir = new File(inputPath); final String[] dirList = dir.list(new FilenameFilter() { public boolean accept(File dir, String name) { if (name.startsWith(".")) { // ignore hidden files return false; } else if (!name.endsWith(".png") && !name.endsWith(".jpg")) { return false; } return true; } }); final Document[] docs = new Document[dirList.length]; BetterThreader.Function<Integer,Object> func = new BetterThreader.Function<Integer,Object>(){public void call(Integer i, Object ignore){ String baseName = dirList[i]; docs[i] = new FirstFolioRawImageDocument(inputPath, baseName, lineHeight, binarizeThreshold); }}; BetterThreader<Integer,Object> threader = new BetterThreader<Integer,Object>(func, numThreads); for (int i=0; i<dirList.length; ++i) threader.addFunctionArgument(i); threader.run(); return Arrays.asList(docs); } }