I'm trying to decode an Aztec barcode using the following script:
import zxing
reader = zxing.BarCodeReader()
barcode = reader.decode("test.png")
print(barcode)
Here is the input image:
Following is the output:
BarCode(raw=None, parsed=None, path='/Users/dhiwatdg/Desktop/test.png', format=None, type=None, points=None)
I'm sure it a valid Aztec barcode. Not the script is not able to decode.
CodePudding user response:
The barcode is not detected because there is a strong "ringing" artifact around the black bars (could be result of "defocus" issue).
We may apply binary threshold for getting higher contrast between black and while.
Finding the correct threshold is difficult...
For finding the correct threshold, we may start with the automatic threshold value returned by cv2.THRESH_OTSU
, and increasing the threshold until the barcode is detected.
(Note that need to increase [and not decrease] the threshold is specific to the image above).
Note:
- The suggested solution is a bit of an overfit, and it's not very efficient.
Other solution I tried, like sharpening were not working...
Code sample:
import cv2
import zxing
reader = zxing.BarCodeReader()
img = cv2.imread('test.png', cv2.IMREAD_GRAYSCALE) # Read the image as grayscale.
thresh, bw = cv2.threshold(img, 0, 255, cv2.THRESH_OTSU) # Apply automatic binary thresholding.
while thresh < 245:
print(f'thresh = {thresh}')
cv2.imshow('bw', bw) # Show bw image for testing
cv2.waitKey(1000) # Wait 1 second (for testing)
cv2.imwrite('test1.png', bw) # Save bw as input image to the barcode reader.
barcode = reader.decode("test1.png", try_harder=True, possible_formats=['AZTEC'], pure_barcode=True) # Try to read the barcode
if barcode.type is not None:
break # Break the loop when barcode is detected.
thresh = 10 # Increase the threshold in steps of 10
thresh, bw = cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY) # Apply binary threshold
cv2.imwrite('bw.png', bw) # Save bw for debugging
cv2.destroyAllWindows()
print(barcode)
Last value of thresh
= 164
.
CodePudding user response:
@Rotem's solution works perfectly. I also found the below solution workable by applying Wiener filter.
import cv2
import zxing
img = cv2.imread("test.png")
dst = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 21)
cv2.imwrite("test_tmp.png", dst)
reader = zxing.BarCodeReader()
barcode = reader.decode("test_tmp.png")
print(barcode)