'QR Code Detection from Pyzbar with Camera Image
I am having trouble detecting QR code using Pyzbar. Under perfection condition, I am able to detect the QR code using the original png image. However, when I do video capture from a camera, and then save that frame as in image, pyzbar fails to detect the QR code.
For example, this works
[Decoded(data=b'GOAL', type='QRCODE', rect=Rect(left=16, top=16, width=168, height=168))]
But the following does not even after I manually cropped the surroundings to only show the QR code.
[]
For both of the images, I am using
decode(image, scan_locations=True)
I am wondering what do I need to do in order for pyzbar to decode my QR code image?
Solution 1:[1]
Used OpenCV
to threshold the image to black-in-white then pyzbar
is able to decode the QR code.
Firstly, threshold the image with the code below.
from pyzbar import pyzbar
import argparse
import numpy as np
import cv2
image =cv2.imread("QRCode.png")
# thresholds image to white in back then invert it to black in white
# try to just the BGR values of inRange to get the best result
mask = cv2.inRange(image,(0,0,0),(200,200,200))
thresholded = cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)
inverted = 255-thresholded # black-in-white
The following is the processed images.
With,
barcodes = pyzbar.decode(inverted)
print (barcodes)
The print out showed the decoded type is QRCODE
and the data is GOAL
.
[Decoded(data='GOAL', type='QRCODE', rect=Rect(left=5, top=13, width=228, height=212),
polygon=[Point(x=5, y=222), Point(x=233, y=225), Point(x=220, y=19), Point(x=13, y=13)])]
Hope this help.
Solution 2:[2]
the problem you are facing is due to the fact that you flipped the image before processing
flipping the image after processing with pyzbar will make it align as you would want it to be
Solution 3:[3]
I found the existing answers didn't work for some images and ended up using this approach.
''' detect and decode QR from image '''
def scan_qr(image, old_method=False):
if image.ndim == 3:
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
else: # ndim == 2
image_gray = image
min_dim = min(image.shape[:2])
block_size = int(min_dim/3)
block_size += 0 if block_size%2 == 1 else 1 # blockSize should be odd
image_bw = cv2.adaptiveThreshold(image_gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, block_size, 2)
return decode(image_bw, symbols=[ZBarSymbol.QRCODE])
I am using adaptiveThreshold as it is better in converting an image of varying brightness to a black & white image.
Your qr looks like this
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Martijn Pieters |
Solution 3 | Avinash Thakur |