Search code examples
pythonimage-processingqr-codezbar

Preprocessing images for QR detection in python


I used Zbar and OpenCV to read the QR code in the image below but both failed to detect it. For ZBar, I use pyzbar library as the python wrapper. There are images that QR is detected correctly and images really similar to the successful ones that fail. My phone camera can read the QR code in the uploaded image which means it is a valid one. Below is the code snippet:

from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol
import cv2

# zbar    
results = decode(cv2.imread(image_path), symbols=[ZBarSymbol.QRCODE])
print(results) 

# opencv
qr_decoder = cv2.QRCodeDetector()
data, bbox, rectified_image = qr_decoder.detectAndDecode(cv2.imread(image_path))
print(data, bbox)

What type of pre-processing will help to increase the rate of success for detecting QR codes?

the image attached


Solution

  • zbar, which does some preprocessing, does not detect the QR code, which you can test running zbarimg image.jpg.

    Good binarization is useful here. I got this to work using the kraken.binarization.nlbin() function of the Kraken library. The library is for OCR, but works very well for QR codes, too, by using non-linear processing. The Kraken binarization code is here.

    Here is the code for the sample:

    from kraken import binarization
    from PIL import Image
    from pyzbar.pyzbar import decode
    from pyzbar.pyzbar import ZBarSymbol
    
    image_path = "image.jpg"
    # binarization using kraken
    im = Image.open(image_path)
    bw_im = binarization.nlbin(im)
    # zbar
    decode(bw_im, symbols=[ZBarSymbol.QRCODE])
    

    [Decoded(data=b'DE-AAA002065', type='QRCODE', rect=Rect(left=1429, top=361, width=300, height=306), polygon=[Point(x=1429, y=361), Point(x=1429, y=667), Point(x=1729, y=667), Point(x=1723, y=365)])]
    

    The following picture shows the clear image of the QR code after binarization:

    Binarized picture