I tried reading this barcode with pyzbar. I've tried at least 2 different approaches for fuzzy barcode filters here on stack overflow, none of them work. I try rotating the barcode to different angles. Doesn't work.
i've tried doing threshold with fuzbar() function, I've tried grayscaling. I've tried rotating it at 360 angles. How can I improve teh quality of this barcode to make it scannable with pyzbar?
Here is my code, I'm running python 2.7 btw:
# Importing library
import cv2
from pyzbar.pyzbar import decode
from pyzbar import pyzbar
import numpy as np
from time import sleep
import math
cv = cv2
def rot3(image, angleInDegrees):
h, w = image.shape[:2]
img_c = (w / 2, h / 2)
rot = cv2.getRotationMatrix2D(img_c, angleInDegrees, 1)
rad = math.radians(angleInDegrees)
sin = math.sin(rad)
cos = math.cos(rad)
b_w = int((h * abs(sin)) + (w * abs(cos)))
b_h = int((h * abs(cos)) + (w * abs(sin)))
rot[0, 2] += ((b_w / 2) - img_c[0])
rot[1, 2] += ((b_h / 2) - img_c[1])
outImg = cv2.warpAffine(image, rot, (b_w, b_h), flags=cv2.INTER_LINEAR)
return outImg
def fuzbar(img):
import matplotlib.pyplot as plt
closed = cv.morphologyEx(img, cv.MORPH_CLOSE, cv.getStructuringElement(cv.MORPH_RECT, (1, 21)))
# #------------------------
# # Statistics
# #========================
print(img.shape)
dens = np.sum(img, axis=0)
mean = np.mean(dens)
print(mean)
#------------------------
# Thresholding
#========================
thresh = closed.copy()
for idx, val in enumerate(dens):
if val< 10800:
thresh[:,idx] = 0
(_, thresh2) = cv.threshold(thresh, 128, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
#------------------------
# plotting the results
#========================
plt.figure(num='barcode')
plt.subplot(221)
plt.imshow(img, cmap='gray')
plt.title('Original')
plt.axis('off')
plt.subplot(224)
plt.imshow(thresh, cmap='gray')
plt.title('Thresholded')
plt.axis('off')
plt.subplot(223)
plt.imshow(thresh2, cmap='gray')
plt.title('Result')
plt.axis('off')
plt.subplot(222)
plt.hist(dens)
plt.axvline(dens.mean(), color='k', linestyle='dashed', linewidth=1)
plt.title('dens hist')
plt.show()
#------------------------
# Printing the Output
#========================
barcodes = pyzbar.decode(thresh2)
print(barcodes)
def cropb(image):
cropped_img = image[image.shape[0]/2:image.shape[0]]
return cropped_img
def rotate(img):
#path = r'C:\Users\user\Desktop\geeks14.png'
# Reading an image in default mode
#src = cv2.imread(path)
# Window name in which image is displayed
#window_name = 'Image'
# Using cv2.rotate() method
# Using cv2.ROTATE_90_CLOCKWISE rotate
# by 90 degrees clockwise
image = cv2.rotate(src, cv2.ROTATE_90_CLOCKWISE)
# Displaying the image
#cv2.imshow(window_name, image)
#cv2.waitKey(0)
def rot2(image, angle):
image_center = tuple(np.array(image.shape[1::-1]) / 2)
rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0)
result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR)
return result
# Make one method to decode the barcode
def BarcodeReader(image):
print 'yep'
# read the image in numpy array using cv2
#img = cv2.imread(image)
img = cv2.imread(image, cv.IMREAD_GRAYSCALE)
# cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
img = cropb(img)
#img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
fuzbar(img)
kernel = np.array([[0, -1, 0],
[-1, 5,-1],
[0, -1, 0]])
img = cv2.filter2D(src=img, ddepth=-1, kernel=kernel)
# Decode the barcode image
detectedBarcodes = decode(img)
# If not detected then print the message
if not detectedBarcodes:
print 'trying loop NO barcode found'
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
origimg = img
zz = 0
while zz != 360:
zz+=1
img = rot3(origimg,zz)
#cv2.resizeWindow("Resized_Window", 200, 500)
#cv2.imshow("Image", img)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
print 'detect at angle', zz
detectedBarcodes = decode(img)
if detectedBarcodes:
break
print 'bob'
if not detectedBarcodes:
print("no angle detect")
return
# Traverse through all the detected barcodes in image
for barcode in detectedBarcodes:
print ('first try found barcodes')
# Locate the barcode position in image
(x, y, w, h) = barcode.rect
# Put the rectangle in image using
# cv2 to highlight the barcode
cv2.rectangle(img, (x-10, y-10),
(x + w+10, y + h+10),
(255, 0, 0), 2)
if barcode.data!="":
# Print the barcode data
print(barcode.data)
print(barcode.type)
print 'done'
image = "tbar.jpg"
BarcodeReader(image)
The issue might be with the focus light or camera's light on the bar code, try turning that off and check, else increasing the contrast or converting the barcode image to black and white should do improve the detection.