001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.tools.imagecollection.tool; 031 032import java.io.File; 033import java.io.IOException; 034 035import org.kohsuke.args4j.CmdLineException; 036import org.kohsuke.args4j.CmdLineParser; 037import org.kohsuke.args4j.Option; 038import org.kohsuke.args4j.ProxyOptionHandler; 039import org.openimaj.image.Image; 040import org.openimaj.image.MBFImage; 041import org.openimaj.io.IOUtils; 042import org.openimaj.tools.imagecollection.collection.ImageCollection; 043import org.openimaj.tools.imagecollection.collection.ImageCollectionSetupException; 044import org.openimaj.tools.imagecollection.collection.config.ImageCollectionConfig; 045import org.openimaj.tools.imagecollection.collection.config.ImageCollectionMode; 046import org.openimaj.tools.imagecollection.collection.config.ImageCollectionProcessorMode; 047import org.openimaj.tools.imagecollection.collection.config.MetaMapperMode; 048import org.openimaj.tools.imagecollection.metamapper.MetaMapper; 049import org.openimaj.tools.imagecollection.processor.ImageCollectionProcessor; 050import org.openimaj.tools.imagecollection.tool.ImageCollectionProcessorJob.ProcessorJobEvent; 051import org.openimaj.tools.imagecollection.tool.ImageCollectionProcessorJob.ProcessorJobListener; 052 053public class ImageCollectionTool<T extends Image<?,T>> implements ProcessorJobListener { 054 @Option(name="--input", aliases="-i", required=false, usage="Input Config File (json)", metaVar="STRING") 055 private String input = null; 056 057 @Option(name="--input-string", aliases="-is", required=false, usage="Input Config String (json).", metaVar="STRING") 058 private String inputString = null; 059 060 @Option(name="--output-mode", aliases="-om", required=false, usage="Image Collection output mode", handler=ProxyOptionHandler.class) 061 private ImageCollectionProcessorMode processorMode = ImageCollectionProcessorMode.DIR; 062 private ImageCollectionProcessorMode.ModeOp processorModeOp; 063 private ImageCollectionProcessor<MBFImage> processor = null; 064 065 @Option(name="--collection-mode", aliases="-cm", required=false, usage="Image Collection to pass json to") 066 private ImageCollectionMode collectionMode = null; 067 private ImageCollection<MBFImage> collection = null; 068 069 @Option(name="--mapper-mode", aliases="-mm", required=false, usage="Imge Collection entry metadata mapper", handler=ProxyOptionHandler.class) 070 private MetaMapperMode mapperMode = MetaMapperMode.FILE; 071 private MetaMapper metaMapper; 072 073 public void setup() throws IOException, ImageCollectionSetupException{ 074 ImageCollectionConfig config; 075 if(input!= null){ 076 config = IOUtils.read(new File(input),ImageCollectionConfig.class); 077 } 078 else if(inputString!= null){ 079 config = new ImageCollectionConfig(inputString); 080 } 081 else{ 082 try{ 083 config = IOUtils.read(System.in,ImageCollectionConfig.class); 084 } 085 catch(ClassCastException t){ 086 throw new IOException("Not parseable!"); 087 } 088 } 089 090 if(collectionMode==null){ 091 collection = ImageCollectionMode.guessType(config); 092 } 093 else{ 094 collection = collectionMode.initCollection(config); 095 } 096 097 if(collection == null){ 098 throw new IOException("Could not read collection"); 099 } 100 101 this.processor = processorModeOp.processor(); 102 this.metaMapper = mapperMode.mapper(this.processor); 103 } 104 105 private void run() { 106 ImageCollectionProcessorJob<MBFImage> job = new ImageCollectionProcessorJob<MBFImage>( 107 this.collection, 108 this.processor, 109 this.metaMapper 110 ); 111 job.addListener(this); 112 Thread t = new Thread(job); 113 t.start(); 114 } 115 116 public static void main(String args[]){ 117 ImageCollectionTool<MBFImage> tool = new ImageCollectionTool<MBFImage>(); 118 CmdLineParser parser = new CmdLineParser(tool); 119 120 try { 121 parser.parseArgument(args); 122 tool.setup(); 123 tool.run(); 124 } catch(CmdLineException e) { 125 parserError(parser,e); 126 } catch (IOException e) { 127 parserError(parser,e); 128 } catch (ImageCollectionSetupException e) { 129 parserError(parser,e); 130 } 131 132 133 } 134 135 private static void parserError(CmdLineParser parser, Exception e) { 136 System.err.println(e.getMessage()); 137 System.err.println("Usage: java -jar ImageCollectionTool.jar [arguments]"); 138 parser.printUsage(System.err); 139 return; 140 } 141 142 @Override 143 public void progressUpdate(ProcessorJobEvent event) { 144 System.out.print("\r"); 145 StringBuilder progress = new StringBuilder(); 146 int progressLen = 100; 147 if(event.validTotal){ 148 149 double progressProp = (double)event.imagesDone / (double)event.imagesTotal; 150 progress.append(String.format("%s/%s",event.imagesDone,event.imagesTotal)); 151 progress.append('['); 152 int currentProgress = (int) (progressLen * progressProp); 153 for(int i = 0; i < currentProgress; i++){ 154 progress.append('#'); 155 } 156 for(int i = currentProgress; i < progressLen; i++){ 157 progress.append(' '); 158 } 159 } 160 else{ 161 progress.append(String.format("%s/%s",event.imagesDone,"?")); 162 progress.append('['); 163 int hashIndex = event.imagesDone % progressLen; 164 if((event.imagesDone / progressLen) % 2 == 1){ 165 hashIndex = progressLen - hashIndex; 166 } 167 168 for(int i = 0; i < progressLen; i++){ 169 if(i == hashIndex) 170 progress.append('#'); 171 else 172 progress.append(' '); 173 } 174 } 175 progress.append(']'); 176 System.out.print(progress.toString()); 177 } 178}