Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decode Micro QR codes with Python

Tags:

python

qr-code

I used "segno" to create Micro QR codes with python:

import segno
segno.make_micro("1").save("1.png", scale=10)

Output Image

Does anyone know of a (simple) way to decode these with python? I could not find a library but I'm afraid that doning this myself (maybe with openCV) will be much effort.

In contrast to this post (How to decode a QR-code image in (preferably pure) Python?) I successfully installed PyQRCode and ZBar, already. Unfortunately these libraries do not decode Micro QR codes.

like image 313
Manu Avatar asked Mar 23 '17 09:03

Manu


2 Answers

Since apparently using Micro QR codes has not become widespread enough (yet?) to merit adding support for reading them in any library I could find, I was looking for a workaround. In my search I came across one or two online QR readers that support decoding micro QR codes. Since I am just learning Playwright for Python, I thought, I'd give it a try.

The code below uses playwright to open an online QR code decoder website, click through the page to set the correct options, upload the image file and then read the result from the page.

I am aware that this is a completely convoluted way and noone would do this in production code, but it was fun and it does work :) Though it does not qualify as "simple" as the OP requested, I'm afraid.

from playwright import sync_playwright
import segno

segno.make_micro("1").save("1.png", scale=10)

with sync_playwright() as p:
   browser = p.firefox.launch(headless=False)
   page = browser.newPage()
   page.goto('https://www.datasymbol.com/barcode-reader-sdk/barcode-reader-sdk-for-windows/online-barcode-decoder.html')
   page.querySelector('select[name=\"sr\"]').selectOption([{'label': 'Text'}])
   page.querySelector('img[alt=\"QRCode Decoder Scanner Settings\"]').click()
   page.querySelector('input[name=\"qrmicro\"]').click()
   page.querySelector('input[id=\"fupload1\"]').setInputFiles('1.png')
   page.querySelector('input[type=\"button\"]').click()
   iframe = page.querySelector('iframe[name=\"f2\"]').contentFrame()
   result = iframe.querySelector('css=pre').innerHTML().rstrip()
   print(result)
   browser.close()

prints

1

Some notes:

  • if you do not want to see the page during execution, simply delete headless=False.
  • apparently, there is a pretty unpleasant limitation to using at least the service I chose: if the text you encode is longer than two characters, the website will change the first two characters to **, so if you encoded One Two Three you will retrieve **e Two Three. This is a limitation if you do not create the barcodes yourself. If you do, simply add ** at the beginning of your contents in the first place.
  • if you do want to use a remote service but don't want the complex way via the web interface, there are services that offer a direct API you can use e.g. with requests. The site I chose above apparently also offers something like that and there seems to be a free plan. But I never used it so I can't say anything about it.
like image 96
buddemat Avatar answered Sep 20 '22 21:09

buddemat


PyBoof just got updated and now supports scanning / reading Micro QR Codes and generating them too. See example code on Github for detecting and creating. Below is a copy of the code for scanning/detecting:

import numpy as np
import pyboof as pb

# Detects all the QR Codes in the image and prints their message and location
data_path = "../data/example/fiducial/microqr/image01.jpg"

detector = pb.FactoryFiducial(np.uint8).microqr()

image = pb.load_single_band(data_path, np.uint8)

detector.detect(image)

print("Detected a total of {} QR Codes".format(len(detector.detections)))

for qr in detector.detections:
    print("Message: " + qr.message)
    print("     at: " + str(qr.bounds))

PyBoof is a wrapper around BoofCV so you might want to check that out also.

like image 27
lessthanoptimal Avatar answered Sep 23 '22 21:09

lessthanoptimal