工作中遇到一个比较繁琐的任务,要每天从一个详表里一条条得复制工单号到我们的系统中,然后搜索出来该工单相关的图片,如果其中有我想要的设备SN码,就算合格,否则为不合格。听起来简单,但该工作有3个坑:
1. 系统很慢,每搜索一次需要30秒以上
2. 图片不显示缩略图,要一个个打开,才能找到想要的设备图片
3. 并不是所有的工单都有图片,有的可能没传,搜了半天白搜了
于是,我首先使用爬虫将图片根据工单号全都爬下来,存到本地,以工单号为名称命名文件夹,然后用python给excel设置上超链接,这样业务员直接点击超链接就能看到图片。
事实证明爬下来几乎不耗时,不知道这网站咋设置的……5分钟不到,一千条全爬完了,直接省了半条命。
随后,我发现有一些图片是很清晰的,SN码可以直接扫描,于是用python的pyzbar,结合opencv对图像的预处理(提高对比度、二值化等),经过反复实验,得出了最优解。代码如下:
import cv2
from pyzbar.pyzbar import decode
from keepValue import keep_alphanumeric
def preprocess_image(image_path):
# 读取图像
image = cv2.imread(image_path)
if image is None:
print(f"Error: 无法打开图像 {image_path}")
return None
else:
print("Image successfully loaded.")
# 将图像转换为灰度
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 锐化操作
sharpened = cv2.GaussianBlur(gray, (0, 0), 1)
sharpened = cv2.addWeighted(gray, 1.5, sharpened, -0.5, 0)
# 增加对比度
alpha = 1.1
beta = 20
contrast = cv2.convertScaleAbs(sharpened, alpha=alpha, beta=beta)
cv2.imwrite("contrast.jpg", contrast)
# 二值化
# _, binary = cv2.threshold(contrast, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return contrast
def extract_barcodes(image_path):
# 进行图像预处理
preprocessed_image = preprocess_image(image_path)
if preprocessed_image is None:
return []
print(f"正在处理{image_path}")
# 使用pyzbar解码器检测所有的条形码
barcodes = decode(preprocessed_image)
res_list = []
# 遍历检测到的所有条形码
for barcode in barcodes:
# 提取条形码的数据
barcode_data = barcode.data.decode("utf-8")
# print(f"条形码数据: {barcode_data}")
res_list.append(barcode_data)
# ocr_res = second_hand(preprocessed_image)
# res_list.extend(ocr_res)
res_list = keep_alphanumeric(res_list)
print("全部结果", res_list)
return res_list
# 调用函数并传递图像路径
if __name__ == "__main__":
extract_barcodes("2.png")
再把这个图像处理封装成一个flask服务,以供别的应用调用即可。做完这一步,自动识别的图片占20%左右,已经减轻很多工作负担了。
想要源码的,关注我,我会后期发布下载资源。