3 import os, sys, argparse
11 filename = os.path.join(path,
'em.py')
12 if os.path.exists(filename):
13 em = imp.load_source(
'em', filename)
14 if "expand" in dir(em):
18 print "ERROR: could not find module em, please sudo apt install python-empy" 22 import cv2.aruco
as aruco
25 Generate a PDF file containaing one or more fiducial marker for printing 29 rc = os.system(
"which %s > /dev/null" % cmd)
31 print """This utility requires %s. It can be installed by typing: 32 sudo apt install %s""" % (cmd, package)
36 return em.expand(
"""<svg width="@(paper_width)mm" height="@(paper_height)mm" 38 xmlns:xlink="http://www.w3.org/1999/xlink" 39 xmlns="http://www.w3.org/2000/svg"> 41 <rect x="@((paper_width - fid_len)/2)mm" y="@((paper_height - fid_len)/2)mm" width="@(fid_len)mm" height="4.0mm" style="stroke:none; fill:black"/> 42 <rect x="@((paper_width - fid_len)/2)mm" y="@((paper_height + fid_len)/2 - 4)mm" width="@(fid_len)mm" height="4.0mm" style="stroke:none; fill:black"/> 43 <rect x="@((paper_width - fid_len)/2)mm" y="@((paper_height - fid_len)/2)mm" width="4.0mm" height="@(fid_len)mm" style="stroke:none; fill:black"/> 44 <rect x="@((paper_width + fid_len)/2 - 4)mm" y="@((paper_height - fid_len)/2)mm" width="4.0mm" height="@(fid_len)mm" style="stroke:none; fill:black"/> 46 <image x="@((paper_width - fid_len)/2)mm" y="@((paper_height - fid_len)/2)mm" width="@(fid_len)mm" height="@(fid_len)mm" xlink:href="/tmp/marker@(id).png" /> 49 @{cut = max(fid_len/10 * 1.4, 10)} 51 @{corner_x = (paper_width - fid_len)/2 - cut} 52 @{corner_y = (paper_height - fid_len)/2 - cut} 53 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x + 2)mm" y2="@(corner_y)mm" style="stroke:black"/> 54 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x)mm" y2="@(corner_y + 2)mm" style="stroke:black"/> 56 @{corner_x = (paper_width + fid_len)/2 + cut} 57 @{corner_y = (paper_height - fid_len)/2 - cut} 58 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x - 2)mm" y2="@(corner_y)mm" style="stroke:black"/> 59 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x)mm" y2="@(corner_y + 2)mm" style="stroke:black"/> 61 <text x="@(paper_width/2)mm" y="@(corner_y - 1)mm" text-anchor="middle" style="font-family:ariel; font-size:8;"> 62 This line should be exactly @(fid_len/10)cm long. 64 <line x1="@(paper_width/2 - fid_len/2)mm" y1="@(corner_y)mm" x2="@(paper_width/2 + fid_len/2)mm" y2="@(corner_y)mm" style="stroke:black"/> 65 <line x1="@(corner_x)mm" y1="@(paper_height/2 - fid_len/2)mm" x2="@(corner_x)mm" y2="@(paper_height/2 + fid_len/2)mm" style="stroke:black"/> 67 @{corner_x = (paper_width - fid_len)/2 - cut} 68 @{corner_y = (paper_height + fid_len)/2 + cut} 69 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x + 2)mm" y2="@(corner_y)mm" style="stroke:black"/> 70 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x)mm" y2="@(corner_y - 2)mm" style="stroke:black"/> 72 <line x1="@(corner_x)mm" y1="@(paper_height/2 - fid_len/2)mm" x2="@(corner_x)mm" y2="@(paper_height/2 + fid_len/2)mm" style="stroke:black"/> 73 <line x1="@(paper_width/2 - fid_len/2)mm" y1="@(corner_y)mm" x2="@(paper_width/2 + fid_len/2)mm" y2="@(corner_y)mm" style="stroke:black"/> 75 @{corner_x = (paper_width + fid_len)/2 + cut} 76 @{corner_y = (paper_height + fid_len)/2 + cut} 77 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x - 2)mm" y2="@(corner_y)mm" style="stroke:black"/> 78 <line x1="@(corner_x)mm" y1="@(corner_y)mm" x2="@(corner_x)mm" y2="@(corner_y - 2)mm" style="stroke:black"/> 80 <text x="@(paper_width/2)mm" y="@((paper_height + fid_len)/2 + 30)mm" text-anchor="middle" style="font-family:ariel; font-size:24;">@(id) D@(dicno)</text> 83 """, {
"id": id,
"dicno": dicno,
"paper_width": paper_size[0],
"paper_height": paper_size[1],
"fid_len": 140.0})
86 print " Marker %d\r" % i,
88 aruco_dict = aruco.Dictionary_get(dicno)
89 img = aruco.drawMarker(aruco_dict, i, 2000)
90 cv2.imwrite(
"/tmp/marker%d.png" % i, img)
91 svg =
genSvg(i, dicno, paper_size)
92 cairo = subprocess.Popen((
'cairosvg',
'-f',
'pdf',
'-o',
'/tmp/marker%d.pdf' % i,
'/dev/stdin'), stdin=subprocess.PIPE)
93 cairo.communicate(input=svg)
97 os.remove(
"/tmp/marker%d.png" % i)
99 if __name__ ==
"__main__":
100 checkCmd(
"pdfunite",
"poppler-utils")
101 checkCmd(
"cairosvg",
"python-cairosvg")
104 parser = argparse.ArgumentParser(description=
'Generate Aruco Markers.')
105 parser.add_argument(
'startId', type=int,
106 help=
'start of marker range to generate')
107 parser.add_argument(
'endId', type=int,
108 help=
'end of marker range to generate')
109 parser.add_argument(
'pdfFile', type=str,
110 help=
'file to store markers in')
111 parser.add_argument(
'dictionary', type=int, default=
'7', nargs=
'?',
112 help=
'dictionary to generate from')
113 parser.add_argument(
'--paper-size', dest=
'paper_size', action=
'store',
114 default=
'letter', help=
'paper size to use (letter or a4)')
116 args = parser.parse_args()
118 outfile = args.pdfFile
119 dicno = args.dictionary
121 markers = range(args.startId, args.endId + 1)
122 pdfs = map(
lambda i:
"/tmp/marker%d.pdf" % i, markers)
124 if args.paper_size ==
'letter':
125 paper_size = (215.9, 279.4)
126 elif args.paper_size ==
'a4':
127 paper_size = (210, 297)
131 from joblib
import Parallel, delayed
132 Parallel(n_jobs=-1)(delayed(genMarker)(i, dicno, paper_size)
for i
in markers)
138 print "Combining into %s" % outfile
139 os.system(
"pdfunite %s %s" % (
" ".join(pdfs), outfile))
143 print '\033[91m' +
"""After printing, please make sure that the long lines around the marker are 144 EXACTLY 14.0 cm long. This is required for accurate position estimation.""" +
'\033[0m' def genSvg(id, dicno, paper_size)
def checkCmd(cmd, package)
def genMarker(i, dicno, paper_size)