/* * Copyright (c) 2011-2016, Peter Abeles. All Rights Reserved. * * This file is part of BoofCV (http://boofcv.org). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package boofcv.app; import boofcv.abst.fiducial.calib.CalibrationPatterns; import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.Option; /** * Application for generating calibration targets * * @author Peter Abeles */ public class CreateCalibrationTarget { @Option(name="-t",aliases = {"--Type"}, usage="Type of calibration target.") String _type=null; CalibrationPatterns type; @Option(name="-r",aliases = {"--Rows"}, usage="Number of rows") int rows=-1; @Option(name="-c",aliases = {"--Columns"}, usage="Number of columns") int columns=-1; @Option(name="-u",aliases = {"--Units"}, usage="Name of document units. default: cm") String _unit = Unit.CENTIMETER.abbreviation; Unit unit; @Option(name="-p",aliases = {"--PaperSize"}, usage="Size of paper used. See below for predefined document sizes. " +"You can manually specify any size using the following notation. W:H where W is the width and H is the height. " +"Values of W and H is specified with <number><unit abbreviation>, e.g. 6cm or 6, the unit is optional. If no unit" +" are specified the default document units are used.") String _paperSize = PaperSize.LETTER.name; PaperSize paperSize; @Option(name="-w",aliases = {"--ShapeWidth"}, usage="Width of the shape or diameter if a circle. In document units.") double shapeWidth=-1; @Option(name="-s",aliases = {"--Space"}, usage="Spacing between the shapes. In document units.") double shapeSpace=-1; @Option(name="-d",aliases = {"--CenterDistance"}, usage="Distance between circle centers. In document units.") double centerDistance=-1; @Option(name="-o",aliases = {"--OutputName"}, usage="Name of output file. E.g. chessboard for chessboard.ps") String fileName = "target"; @Option(name="-i",aliases = {"--DisablePrintInfo"}, usage="Disable printing information about the calibration target") boolean disablePrintInfo = false; private static void printHelpExit( CmdLineParser parser ) { parser.getProperties().withUsageWidth(120); parser.printUsage(System.out); System.out.println(); System.out.println("Target Types"); for( CalibrationPatterns p : CalibrationPatterns.values() ) { System.out.println(" "+p); } System.out.println(); System.out.println("Document Types"); for( PaperSize p : PaperSize.values() ) { System.out.printf(" %12s %5.0f %5.0f %s\n",p.getName(),p.width,p.height,p.unit.abbreviation); } System.out.println(); System.out.println("Units"); for( Unit u : Unit.values() ) { System.out.printf(" %12s %3s\n",u,u.abbreviation); } System.out.println(); System.out.println("Examples:"); System.out.println("-r 8 -c 5 -o target -t CIRCLE_ASYMMETRIC_GRID -u cm -w 2 -d 6 -p LETTER"); System.out.println(" circle assymetric grid target, grid 8x5, 2cm diameter, 6cm distance, on letter paper"); System.out.println(); System.out.println("-r 4 -c 3 -o target -t SQUARE_GRID -u cm -w 3 -s 3 -p LETTER"); System.out.println(" square grid target, grid 4x3, 3cm squares, 3cm space, on letter paper"); System.out.println(); System.out.println("-r 7 -c 5 -o target -t CHESSBOARD -u cm -w 3 -p LETTER"); System.out.println(" square grid target, grid 7x5, 3cm squares, on letter paper"); System.out.println(); System.exit(1); } private static void failExit( String message ) { System.err.println(message); System.exit(1); } private void finishParsing(CmdLineParser parser) { if( rows <= 0 || columns <= 0 || _type == null ) printHelpExit(parser); for( CalibrationPatterns p : CalibrationPatterns.values() ) { if( _type.compareToIgnoreCase(p.name() ) == 0 ) { type = p; break; } } if( type == null ) { failExit("Must specify a known document type "+_type); } unit = Unit.lookup(_unit); if( unit == null ) { System.err.println("Must specify a valid unit or use default"); System.exit(1); } paperSize = PaperSize.lookup(_paperSize); if( paperSize == null ) { String words[] = _paperSize.split(":"); if( words.length != 2) failExit("Expected two value+unit separated by a :"); LengthUnit w = new LengthUnit(words[0]); LengthUnit h = new LengthUnit(words[1]); if( w.unit != h.unit ) failExit("Same units must be specified for width and height"); paperSize = new PaperSize(w.length,h.length,w.unit); } if( rows <= 0 || columns <= 0) failExit("Must the number of rows and columns"); if( shapeWidth <= 0 ) failExit("Must specify a shape width more than zero"); switch( type ) { case BINARY_GRID: case SQUARE_GRID: if( centerDistance > 0 ) failExit("Don't specify center distance for square type targets, use shape space instead"); if( shapeSpace <= 0 ) shapeSpace = shapeWidth; break; case CHESSBOARD: if( centerDistance > 0 ) failExit("Don't specify center distance for chessboard targets"); if( shapeSpace > 0 ) failExit("Don't specify center distance for chessboard targets"); break; case CIRCLE_ASYMMETRIC_GRID: if( shapeSpace > 0 ) failExit("Don't specify space for circle type targets, use center distance instead"); if( centerDistance <= 0 ) centerDistance = shapeWidth*2; break; } } public void run() { String suffix = ".ps"; System.out.println("Saving to "+fileName+suffix); CreateCalibrationTargetGenerator generator = new CreateCalibrationTargetGenerator(fileName+suffix,paperSize,rows,columns,unit); generator.setShowInfo(!disablePrintInfo); System.out.println(" paper : "+paperSize); System.out.println(" type : "+type); System.out.println(" rows : "+rows); System.out.println(" columns : "+columns); System.out.println(" info : "+(!disablePrintInfo)); switch( type ) { case CHESSBOARD:generator.chessboard(shapeWidth);break; case SQUARE_GRID:generator.squareGrid(shapeWidth,shapeSpace);break; case BINARY_GRID:generator.binaryGrid(shapeWidth,shapeSpace);break; case CIRCLE_ASYMMETRIC_GRID:generator.circleAsymmetric(shapeWidth,centerDistance);break; default: throw new RuntimeException("Unknown target type"); } } public static void main(String[] args) { CreateCalibrationTarget generator = new CreateCalibrationTarget(); CmdLineParser parser = new CmdLineParser(generator); try { parser.parseArgument(args); generator.finishParsing(parser); generator.run(); } catch (CmdLineException e) { // handling of wrong arguments System.err.println(e.getMessage()); printHelpExit(parser); } } }