Skip to content

Instantly share code, notes, and snippets.

@Brockhold
Created November 11, 2022 23:58
Show Gist options
  • Save Brockhold/0b6640a2af90799d84867233222c1cad to your computer and use it in GitHub Desktop.
Save Brockhold/0b6640a2af90799d84867233222c1cad to your computer and use it in GitHub Desktop.
16H5 Apriltag Generator
#! /usr/bin/python3
# Generate and dump the complete set of 16H5 AprilTags in spec for use as FRC 2023 vision targets.
# Outputs 30 SVG images containing white 8-inch squares, inside of which are centered 6-inch 16H5 tags.
# Files are dropped in working directory, with filenames following the pattern of "tag16h5_#.svg" with # from 0 to 29
#
# With appreciation for the more featureful generator the numpy and svgwrite code derives from:
# https://iosoft.blog/2019/09/02/raspberry-pi-position-detection-fiducial-tags/
import math
#import sys
try:
import numpy as np
import svgwrite
from PIL import Image
except ImportError as e:
print(e,
"""
did you remember to source (or create) a venv with the dependencies?
python3 -m venv tag_venv
. tag_venv/bin/activate
pip3 install numpy svgwrite pillow
""")
quit()
tagArea = 16
#tagMinHammingDistance = 5
tag16h5Codes = (
0x231b, 0x2ea5, 0x346a, 0x45b9, 0x79a6, 0x7f6b,
0xb358, 0xe745, 0xfe59, 0x156d, 0x380b, 0xf0ab,
0x0d84, 0x4736, 0x8c72, 0xaf10, 0x093c, 0x93b4,
0xa503, 0x468f, 0xe137, 0x5795, 0xdf42, 0x1c1d,
0xe9dc, 0x73ad, 0xad5f, 0xd530, 0x07ca, 0xaf2e
)
def gen_tag(val):
dim = int(math.sqrt(tagArea))
d = np.frombuffer(np.array(tag16h5Codes[val], ">i8"), np.uint8)
bits = np.unpackbits(d)[-tagArea:].reshape((-1,dim))
bits = np.pad(bits, 1, 'constant', constant_values=0)
return np.pad(bits, 1, 'constant', constant_values=1)
if __name__ == '__main__':
tags = [gen_tag(n) for n in range(len(tag16h5Codes))]
for a,b in enumerate(tags):
fname = "tag16h5_" + str(a) + ".svg"
VIEW_BOX = "0 0 8 8"
DWG_SIZE = "%uin"%(8),"%uin"%(8)
svg = svgwrite.Drawing(fname, size=DWG_SIZE, viewBox=VIEW_BOX, debug=False)
bg = svg.g(stroke='none', fill='white')
bg.add(svg.rect((0, 0), (8,8)))
svg.add(bg)
g = svg.g(stroke='none', fill='black')
for dy,dx in np.column_stack(np.where(b == 0)):
g.add(svg.rect((dx, dy), (1,1)))
svg.add(g)
print("Creating file %s" % (fname))
svg.save(pretty=True)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment