/
CreateFiducialSquareImageEPS.java
148 lines (122 loc) · 4.95 KB
/
CreateFiducialSquareImageEPS.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* Copyright (c) 2011-2015, 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.distort.FDistort;
import boofcv.alg.filter.binary.ThresholdImageOps;
import boofcv.io.UtilIO;
import boofcv.io.image.UtilImageIO;
import boofcv.struct.image.ImageUInt8;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintStream;
/**
* Outputs an EPS document describing a binary square fiducial that encodes the specified number
*
* @author Peter Abeles
*/
public class CreateFiducialSquareImageEPS {
public static String outputName = "fiducial_image.eps";
public static String inputPath = UtilIO.getPathToBase()+"data/applet/fiducial/image/dog.png";
public static double width = 10; // in centimeters of fiducial
public static int threshold = 255/2; // threshold for converting to a binary image
public static double CM_TO_POINTS = 72.0/2.54;
// should it add the file name and size to the document?
public static boolean displayInfo = true;
public static String binaryToHex( ImageUInt8 binary ) {
if( binary.width%8 != 0 )
throw new RuntimeException("Width must be divisible by 8");
StringBuilder s = new StringBuilder(binary.width*binary.height/4);
for (int y = binary.height-1; y >= 0 ; y--) {
int i = y*binary.width;
for (int x = 0; x < binary.width; x += 8, i+= 8) {
int value = 0;
for (int j = 0; j < 8; j++) {
value |= binary.data[i+j] << (7-j);
}
String hex = Integer.toHexString(value);
if( hex.length() == 1 )
hex = "0"+hex;
s.append(hex);
}
}
return s.toString();
}
public static void main(String[] args) throws FileNotFoundException {
if( args.length == 2 ) {
width = Double.parseDouble(args[0]);
inputPath = args[1];
}
String inputName = new File(inputPath).getName();
System.out.println("Target width "+width+" (cm) image = "+inputName);
System.out.println(" input path = "+inputPath);
ImageUInt8 image = UtilImageIO.loadImage(inputPath,ImageUInt8.class);
if( image == null ) {
System.err.println("Can't find image. Path = "+inputPath);
System.exit(0);
}
// make sure the image is square and divisible by 8
int s = image.width - (image.width%8);
if( image.width != s || image.height != s ) {
ImageUInt8 tmp = new ImageUInt8(s, s);
new FDistort(image, tmp).scaleExt().apply();
image = tmp;
}
// print out the selected number in binary for debugging purposes
PrintStream out = new PrintStream(outputName);
double targetLength = width*CM_TO_POINTS;
double whiteBorder = Math.max(2*CM_TO_POINTS,targetLength/4.0);
double blackBorder = targetLength/4.0;
double innerWidth = targetLength/2.0;
double pageLength = targetLength+whiteBorder*2;
double scale = image.width/innerWidth;
ImageUInt8 binary = ThresholdImageOps.threshold(image,null,threshold,false);
// ShowImages.showWindow(VisualizeBinaryData.renderBinary(binary, false, null), "Binary Image");
out.println("%!PS-Adobe-3.0 EPSF-3.0\n" +
"%%Creator: BoofCV\n" +
"%%Title: "+inputName+" w="+width+"cm\n" +
"%%DocumentData: Clean7Bit\n" +
"%%Origin: 0 0\n" +
"%%BoundingBox: 0 0 "+pageLength+" "+pageLength+"\n" +
"%%LanguageLevel: 3\n" +
"%%Pages: 1\n" +
"%%Page: 1 1\n" +
" /wb "+whiteBorder+" def\n" +
" /bb "+blackBorder+" def\n" +
" /b0 "+whiteBorder+" def\n" +
" /b1 { wb bb add} def\n" +
" /b2 { b1 "+innerWidth+" add} def\n" +
" /b3 { b2 bb add} def\n" +
"% bottom top left right borders..\n" +
" newpath b0 b0 moveto b0 b3 lineto b1 b3 lineto b1 b0 lineto closepath fill\n" +
" newpath b1 b2 moveto b1 b3 lineto b3 b3 lineto b3 b2 lineto closepath fill\n" +
" newpath b1 b0 moveto b1 b1 lineto b3 b1 lineto b2 b0 lineto closepath fill\n" +
" newpath b2 b0 moveto b2 b3 lineto b3 b3 lineto b3 b0 lineto closepath fill\n");
// print out encoding information for convenience
if( displayInfo ) {
out.print(" /Times-Roman findfont\n" +
"7 scalefont setfont b1 " + (pageLength - 10) + " moveto (" + inputName + " " + width + " cm) show\n");
}
out.println("% Drawing the image");
out.println("b1 b1 translate");
out.println(binary.width+" "+binary.height+" 1 ["+scale+" 0 0 "+scale+" 0 0]");
out.println("{<" + binaryToHex(binary) + ">} image");
out.print(" showpage\n" +
"%%EOF\n");
System.out.println("Saved to "+new File(outputName).getAbsolutePath());
}
}