使用pyzbar在python中读取模糊的条形码 [英] Read blurry barcode in python with pyzbar
问题描述
我一直在尝试使用python和pyzbar从图像中读取一些条形码.不幸的是,在几个约束下,图像是从几英尺远的地方拍摄的,我无法更近地移动或变焦相机.是否可以使用任何现有的Python库读取这种模糊的条形码?
I have been trying to read some barcodes from images uzing Python and pyzbar. Unfortunately, the images are taken from several feet away under several constraints and I cannot move or zoom the camera any closer. Is it possible to read barcodes this blurry using any existing Python libraries?
到目前为止,我已经尝试了一些预处理,包括阈值化,锐化,应用垂直关闭滤镜和Wiener滤镜,但似乎没有任何帮助.我可能想问一个奇迹,但是如果您有任何建议,我将不胜感激.
So far I've tried some preprocessing including thresholding, sharpening, applying a vertical closing filter, and Wiener filtering, but none seem to help. I am probably asking for a miracle, but if you have any suggestions I would really appreciate it.
代码(有注释的部分是我尝试过的没有成功的预处理方法):
Code (commented sections are preprocessing methods I have tried with no success):
import numpy as np
import cv2 as cv
from pyzbar import pyzbar
barcode_img = cv.imread('barcode_example.jpg', cv.IMREAD_GRAYSCALE)
# threshold
# (_, barcode_img) = cv.threshold(barcode_img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
# close
# barcode_img = cv.morphologyEx(barcode_img, cv.MORPH_CLOSE,
# cv.getStructuringElement(cv.MORPH_RECT, (1, 21)))
# sharpen
# barcode_img_blur = cv.GaussianBlur(barcode_img, (15, 1), 3)
# barcode_img = cv.addWeighted(barcode_img, 1.5, barcode_img_blur, -0.5, 0)
# wiener filter
# from skimage import img_as_float
# from skimage.restoration import wiener, unsupervised_wiener
# dim = 3
# psf = np.ones((dim, dim)) / dim ** 2
# barcode_img = wiener(barcode_img, psf, 1.0, clip=False)
barcodes = pyzbar.decode(barcode_img)
print(barcodes)
推荐答案
- 这不是最佳的解决方案,如果您的想法有所改善,请与我们分享,以便我们所有人都可以学习.
- 因此,根据一些统计信息,知道它是一个条形码,所以有一个垂直黑色区域代表每个条形码,所以我对行进行了汇总,并根据接近和的平均值的经验值对整个图像进行阈值处理,我通过以下方式解决了该问题:
- This is not the optimal solution, if you have an improvement in your mind please share it with us so we all can learn.
- so depending on some statistics knowing that it's a barcode so there is a vertical black zone to represent each bar, so I did the summation of the rows, and thresholded the whole image depending on an empirical value near the mean of the summation, I solved the problem with this way:
#========================
# Import Libraies
#========================
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from pyzbar import pyzbar
#------------------------
# Read Image
#========================
img = cv.imread('barcode_example.jpg', cv.IMREAD_GRAYSCALE)
# #------------------------
# # Morphology
# #========================
# # Closing
# #------------------------
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)
输出为: [已解码(data = b'00004980072868003004',type ='CODE128',rect = Rect(left = 34,top = 0,width = 526,height = 99),多边形= [点(x = 34,y = 1),点(x = 34,y = 99),点(x = 560,y = 98),点(x = 560,y = 0)])]]
这篇关于使用pyzbar在python中读取模糊的条形码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!