1

I have a library of hundreds of pictures from which I need to extract information encoded in a QR code in each picture.

For 70% of the pictures, pyzbar simply works. For more difficult cases, I try non-linear binarization of the image as suggested by this post: https://stackoverflow.com/a/61443430/1579211

This gets me another 15-20% of the way.

But for about 10% of the images this fails:

from PIL import Image
from pyzbar.pyzbar import decode, ZBarSymbol
from kraken.binarization import nlbin

def read_QRcode(image):
    codes = decode(image, symbols=[ZBarSymbol.QRCODE])
    if not codes:
        codes = decode(nlbin(image), symbols=[ZBarSymbol.QRCODE])
    
    if not codes:
        raise RuntimeError(
            f'Could not decode a QR code from {image.filename}...'
        )
        
    return codes

image = Image.open('sample.jpg')
read_QRcode(image)

When I open up these images (attached sample.jpg) on the screen, my phone, which has a QR scanner built into the camera app, can decode this QR code correctly (see attached screenshot or try yourself).

Does anyone feel up-to the challenge to help me figure this out?

sample image

iPhone screenshot

Shahar
  • 886
  • 1
  • 10
  • 22
  • Can you manually decode the given example by hand / have you tried? QR codes optionally have redundancy built in to allow them to be read if they are obscured or fade or whatever. Do you know what level is used for the QR codes you are reading? I haven't taken the time to manually analyze this one but google lens can't decode or recognize it and it would be using an mlkit based neural net so my guess is that there isn't enough information in this image to decode the given QR code. – David Oldford Nov 23 '20 at 17:42
  • Now looking at your post again I'm left wondering if I just missed that part the first time through or if you added it after my comment :P It looks like your phone is an iphone, I was able to scan the code from the image with an ipad but only occasionally by moving rotating it and moving it around till it finally processed it. Are you able to use the Apple vision API given your constraints? https://developer.apple.com/documentation/vision – David Oldford Nov 23 '20 at 21:54
  • I assume Apple's vision API uses an ML model like what Google provides with MLKit (which I assume google lens uses.) MLKit as far as I know has no desktop support. If you had some macs and maybe some NVIDIA shields you could use what you have then fall back to the next fastest and then the third fastest. You might also try adjusting the orientation, doing some cropping and maybe changing the contrast before you send them to the ML based systems. – David Oldford Nov 23 '20 at 21:59
  • Thank you for your comments @DavidOldford, I did not add or edit my original post ;) – Shahar Nov 24 '20 at 09:04
  • I don't want to read it manually. I want to come up with a smart way of scripting this so it fails only when really too much of the QR code information is missing. I think that will get me to almost 100%. – Shahar Nov 24 '20 at 09:07
  • Oh I don't recommend doing it manually, if you have access to a mac you can use the same apple vision api as your phone used, additionally with any device running Android (I recommend a shield for how powerful they are,) you could write a server that uses ML-Kit and use the google api though as I mentioned it had a hard time decoding that QR code. – David Oldford Nov 25 '20 at 00:30
  • I am now experimenting with the PyObjC wrappers to the various framework APIs. It is not very well documented so I am struggling a bit, but I'll figure it out. Will post something here when I do for future reference. – Shahar Nov 26 '20 at 08:26
  • @DavidOldford I am stuck. Do you have experience with Apple's Vision API? I have posted another question [here](https://stackoverflow.com/questions/65089059/how-do-i-read-an-image-from-file-for-use-with-the-pyobjc-vision-framework) on that... – Shahar Dec 03 '20 at 16:22

0 Answers0