LIGHT DARK
homeresearchpublicationspostsaboutCV
METHODS, CODING, PYTHON

Generate tiny QR code paper tags in Python

Apr 21, 2023 Moritz Lürig Apr 21, 2023 Moritz Lürig

When capturing an organism using digital imaging we often need to connect information on the specimen, i.e., where, when and how it was captured, with phenotypic or taxonomic information, i.e., body size or species name. Most scientists do this via unique ID tags; short alphanumeric sequences printed on white paper or plastic that are included with the specimen inside the image. However, while recognizing the tag inside the image, and extracting the information might be a simple task for a human (that is, if the code is short enough and of sufficient size), it’s much harder for computer vision (CV) algorithms.

When capturing an organism using digital imaging we often need to connect information on the specimen, i.e., where, when and how it was captured, with phenotypic or taxonomic information, i.e., body size or species name. Most scientists do this via unique ID tags; short alphanumeric sequences printed on white paper or plastic that are included with the specimen inside the image. However, while recognizing the tag inside the image, and extracting the information might be a simple task for a human (that is, if the code is short enough and of sufficient size), it’s much harder for computer vision (CV) algorithms.

The task of detecting alphanumeric characters in images is referred to as optical character recognition (OCR), and while there are some good OCR-engines out there (e.g., tesseract), QR codes represent a much better way for automatic text extraction from images. QR codes with their position and alignment patterns are much more easily recognizable by CV algorithms than plain text, which can come in any form or structure. Moreover, QR codes can store more than enough information for basic ID tagging purposes (e.g., even the micro variant can store up to 35 numeric characters.

Try the gist at the bottom of this post to produce hundreds of small QR codes in Python for your next field survey or lab experiment. Naturally, the little tags also include human readable version of the text you wish to encode. The Python-code can be easily modified to also include letters, symbols, etc. - if you have questions or need help feel free to contact me. You can download a sample batch of QR codes here.

GitHub gist to produce QR codes in Python:

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 21 17:08:35 2023
@author: mluerig
"""
#%% imports
import os
import copy
import qrcode
from PIL import Image, ImageDraw, ImageFont, ImageOps
#%% setup
## config QR code area
box_size = 4
font_size = 30
## dummy qr code for up to 4 digits to get width/height
text = "9999"
qr = qrcode.QRCode(version=1,box_size=box_size,border=1)
qr.add_data(text)
qr.make(fit=True)
qr_code = qr.make_image(fill='black', back_color='white')
W, H = copy.deepcopy(qr_code.size)
font = ImageFont.truetype("arial.ttf", font_size)
## config A4 page
max_idx = 1000
max_width, max_height = 2480, 3508
## start index
idx = 0
#%% run
## loop until max number is reached
while idx < max_idx:
## start index for page
idx_curr = idx + 1
## new page
a4_page = Image.new('RGB', (max_width ,max_height), 'white')
## page width/height control
for i in range(100, max_width, W*2 + 26):
if i + W*2 + 20 > max_width:
continue
for j in range(100, max_height, H + 23):
if j + H + 20 > max_height:
continue
## index counter
idx +=1
text = str(copy.deepcopy(idx))
## qr code
qr = qrcode.QRCode(version=1,box_size=box_size,border=1)
qr.add_data(text)
qr.make(fit=True)
qr_code = qr.make_image(fill='black', back_color='white')
## number tag
tag = Image.new("RGBA", (W, H), "white")
draw = ImageDraw.Draw(tag)
_, _, w, h = draw.textbbox((0,0), text=text)
draw.text(((W-w)/4,(H-h)/2.5), text, font=font, fill="black")
## merge
dst = Image.new('RGB', (qr_code.size[0] + tag.size[1], qr_code.size[0]))
dst.paste(qr_code, (0, 0))
dst.paste(tag, (qr_code.size[0], 0))
dst = ImageOps.expand(dst, border=1, fill=(0,0,0))
## add to A4 page
a4_page.paste(dst, (i,j))
## save to pdf
a4_page.save(r"QR_codes_{}-{}.pdf".format(idx_curr, idx), format='pdf', quality=100)
## progress
print("DONE {}-{}".format(idx_curr, idx))
view raw qr_tags.py hosted with ❤ by GitHub
Previous
Creating a small color and size reference card
Next
High throughput imaging of aquatic invertebrates
© Moritz Lürig 2025