条形码检测算法实现与效果分析:提升超市图书馆效率的关键技术

目录

条形码检测算法实现与效果分析:提升超市图书馆效率的关键技术

一、场景需求简介

在现实场景中,我们时常会碰到条形码。它的主要功能是标识物体,让每一个物体都拥有唯一的编号。这样做能够大幅提高查找效率等。比较常见的应用场景有超市和图书馆等。售货员通过扫描这些条形码,就能迅速得知这个商品的价格,极大地提升了用户的购物体验。具体示例如下:

二、算法实现步骤 三、图片中条形码检测代码实现

# coding=utf-8
# 导入python包
import numpy as np
import argparse
import imutils
import cv2
# 构建并解析参数
使用 argparse.ArgumentParser 创建了一个对象 ap 。
ap 添加了一个参数“-i”,也称为“--image”,这个参数是必需的,它的作用是提供图像文件的路径,用于帮助用户指定要处理的图像文件的位置。
args = vars(ap.parse_args())
# 读取图片并将其转化为灰度图片
使用 cv2 库的 imread 函数读取了指定路径的图像,将读取到的图像赋值给变量 image 。
image1 = image.copy()
cv2 将图像从 BGR 颜色空间转换为灰度颜色空间,转换后的结果赋值给 gray 变量,即 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) 。
# 计算图像中x和y方向的Scharr梯度幅值表示
如果 imutils.is_cv2(),那么 ddepth = cv2.cv.CV_32F;否则,ddepth = cv2.CV_32F。
gradX 是通过 cv2.Sobel 函数计算得到的,该函数的输入是灰度图像 gray,ddepth 参数指定了输出图像的深度,dx 参数为 1 表示在 x 方向上求导,dy 参数为 0 表示在 y 方向上不求导,ksize 参数为 -1 表示使用 3x3 的 Sobel 核。
gradY 等于 cv2 对 gray 进行 Sobel 操作,其中 ddepth 为 ddepth,dx 为 0,dy 为 1,ksize 为-1
# x方向的梯度减去y方向的梯度
gradient 是通过 cv2.subtract(gradX, gradY) 这个操作得到的
# 获取处理后的绝对值
gradient 等于通过 cv2.convertScaleAbs 函数对 gradient 进行转换并取绝对值后的结果。
使用 cv2 库将名为“gradient.png”的文件写入,写入的内容是变量 gradient 所代表的图像数据。
# 对处理后的结果进行模糊操作
cv2 对梯度进行模糊处理,模糊核大小为 (9, 9),得到的模糊结果赋值给 blurred
# 将其转化为二值图片
cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY) 的返回值为 (_, thresh)
使用 cv2 库将 thresh 保存为 thresh.png 文件。
# 构建一个掩码并将其应用在二值图片中
kernel 是通过 cv2.getStructuringElement 函数获取的,该函数使用 cv2.MORPH_RECT 形态学结构元素,其尺寸为 (21, 7) 。
cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel) 的结果为 closed
使用 cv2 库将 closed 数组保存为名为 "closed1.png" 的图像文件。
# 执行多次膨胀和腐蚀操作
cv2.erode 函数对 closed 进行操作,使用 None 作为核,迭代次数为 4,操作后的结果赋值给 closed 。
cv2 对 closed 进行膨胀操作,使用 None 作为核,迭代次数为 4,得到的结果赋值给 closed 。
使用 cv2 库将 closed 数组保存为名为 "closed2.png" 的图像文件。
在二值图像里寻找轮廓,接着依据这些轮廓的区域大小来对它们进行排序,最后把最大的那个轮廓保留下来。
cv2 找到轮廓,轮廓的来源是 closed 的副本,使用的模式是 cv2.RETR_EXTERNAL,近似方法是 cv2.CHAIN_APPROX_SIMPLE,找到的轮廓存储在 cnts 中
cnts 被 imutils 抓取到了轮廓(cnts)。
首先找到 cnts 列表,然后使用 sorted 函数按照 cv2.contourArea 作为关键字进行排序,排序顺序为降序,最后获取排序后的列表中的第一个元素并赋值给 c 。
# 计算最大的轮廓的最小外接矩形
rect = cv2.minAreaRect(c)
如果 imutils.is_cv2(),则 box = cv2.cv.BoxPoints(rect);否则,box = cv2.boxPoints(rect)
box = np.int0(box)
# 绘制并显示结果
cv2 把轮廓绘制在 image1 上,绘制的轮廓是[box],轮廓的索引为-1,线条颜色是(0, 255, 0),线条宽度是 3
将 image 和 image1 进行水平堆叠,结果存储在 result 中,即 result 等于 np.hstack([image, image1]) 。
将“detect1.png”作为文件名,把“result”写入其中,使用 cv2 库的 imwrite 函数进行操作。
cv2.imshow("Image", result)
cv2.waitKey(0)

四、图片中条形码检测效果展示与分析

上图展示了该算法在图片中的检测结果和中间结果。第 1 行第 1 列表示原始输入图片,在代码中是 image,此图片含有一个条形码;第 1 行第 2 列表示梯度差绝对值的效果,对应代码中的 gradient,通过此操作能发现含有条形码的区域较明显;第 2 行第 1 列表示二值化后的结果,对应代码中的 thresh,经二值化操作可去除大量噪声,检测出二维码大致位置;第 2 行第 2 列表示应用掩模后的效果图,对应代码中的 closed,可发现应用掩模后结果填补了条形码中大部分空洞;第 3 行第 1 列表示经过膨胀和腐蚀操作后的结果,对应代码中的 closed,可知多次操作可去除大量空洞和噪声;第 3 行第 2 列表示算法最终检测结果,对应代码中的 image1,能发现该算法准确检测出图片中的条形码。

五、视频中条形码检测代码实现

# coding=utf-8
# 导入python包
使用 imutils 库中的视频模块 VideoStream
import numpy as np
import imutils
import argparse
import time
import cv2
# 定义简单的图片检测函数,这个思路就是单张图片的检测思路
def detect(image):
cv2 把图像从 BGR 颜色空间转换为灰度颜色空间,转换后的结果赋值给 gray 变量。
如果 imutils.is_cv2(),那么 ddepth = cv2.cv.CV_32F;否则,ddepth = cv2.CV_32F
gradX 是通过 cv2.Sobel 函数计算得到的,该函数的输入是灰度图像 gray,ddepth 被设置为特定值,dx 为 1,dy 为 0,ksize 被设置为 -1
gradY 是通过 cv2.Sobel 函数计算得到的,该函数的参数包括灰度图像 gray,深度参数 ddepth 为指定值,dx 为 0,dy 为 1,ksize 为 -1 。
gradient 是通过 cv2.subtract(gradX, gradY) 这个操作得到的
gradient 等于 cv2.convertScaleAbs(gradient) 这个操作将 gradient 进行了转换并取绝对值。
cv2 对梯度进行模糊处理,使用的核大小为(9, 9),模糊后的结果赋值给 blurred 变量
在进行图像相关操作时,首先获取到了 blurred 这个图像数据。然后通过 cv2.threshold 函数进行阈值处理,将 blurred 图像中像素值大于等于 225 的部分设置为 255,小于 225 的部分设置为 0,处理结果被存储在一个元组中,其中第一个元素是阈值处理后的图像数据,第二个元素是阈值本身,即 (_, thresh) = cv2.threshold(blurred, 225, 255, cv2.THRESH_BINARY)。
cv2 获得了一个结构元素,其类型为 cv2.MORPH_RECT,大小为 (21, 7),这个结构元素被赋值给了 kernel 变量。
cv2 对 thresh 进行形态学操作,使用的操作是 cv2.MORPH_CLOSE,核为 kernel,最终结果赋值给 closed,即 closed 等于 cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
cv2.erode(closed, None, iterations=4) 的结果赋值给 closed 。
cv2 对 closed 进行膨胀操作,使用 None 作为核,迭代次数为 4,得到的结果赋值给 closed
cnts 是通过 cv2.findContours 函数对 closed 的副本进行操作得到的,该函数使用的检索模式为 cv2.RETR_EXTERNAL。
		cv2.CHAIN_APPROX_SIMPLE)
使用 imutils 抓取轮廓,得到的轮廓为 cnts
	if len(cnts) == 0:
		return None
首先,对 cnts 进行排序,排序的依据是 cv2.contourArea 这个函数,排序的方式是降序排列。然后,取排序后的第一个元素赋值给 c 。
	rect = cv2.minAreaRect(c)
如果使用的是 imutils.is_cv2(),则 box 等于 cv2.cv.BoxPoints(rect);如果不是使用 imutils.is_cv2(),则 box 等于 cv2.boxPoints(rect)
	box = np.int0(box)
	return box
# 构建并解析参数
ap = argparse.ArgumentParser()
ap 添加了一个参数“-v”,也称为“--video”,其作用是提供(可选的)视频文件的路径。
args = vars(ap.parse_args())
# 如果视频不存在则进行视频捕获
如果不是 args 中包含“video”且其值为 False 的情况。
使用 VideoStream 并将其源设置为 0 后启动它,得到的结果赋值给 vs 。
	time.sleep(2.0)
# 否则装载视频
else:
cv2.VideoCapture(args["video"]) 被赋值给了 vs
# 循环处理每一帧
while True:
	# 获取当前帧
	frame = vs.read()
如果 args 中的"video"为 True,则 frame 等于 frame[1];如果 args 中的"video"为 False,则 frame 等于 frame。
 
	# 判断是否达到视频的最后一帧
	if frame is None:
		break
	# 进行单张图片检测
	box = detect(frame)
	# 如果发现了条形码则绘制结果
	if box is not None:
cv2 会在 frame 上绘制轮廓,所绘制的轮廓是 [box],轮廓的索引为 -1,线条颜色为 (0, 255, 0),线条宽度为 2
	# 显示当前帧的结果
	cv2.imshow("Frame", frame)
	key = cv2.waitKey(1) & 0xFF
	# 当用户按下q键时退出整个循环
	if key == ord("q"):
		break
# 停止视频捕获
if not args.get("video", False):
	vs.stop()
# 否则释放内存
else:
	vs.release()
# 关闭所有的窗口
cv2.destroyAllWindows()

六、视频中条形码检测效果展示与分析

该算法在视频上的检测结果如上图所示。此算法在图片中条形码检测的基础上,增添了一些视频控制的代码。整个代码默认会读取视频,若用户未设置读取的视频,代码会调用电脑上的摄像头进行视频捕获,且会实时检测当前帧中是否包含条形码,若包含则显示该条形码,若不包含则不显示任何东西。整个捕获过程会一直持续,直至用户按下键盘上的 q 键为止。观察上图后我们能发现,此代码能够实时地检测到视频中所包含的二维码,并且检测结果是准确的。

七、思维扩展

本文实现了一个简单的图像条形码检测算法。若要实现更强大的条形码检测算法,需考虑图像的方向,尝试应用机器学习技术,比如利用 haar 级联或 hog+linear svm 去“扫描”图像的条形码区域。

本文实现的基于视频的条形码检测算法基于两个假设来设计。其一,我们拥有一个静态摄像头,该摄像头以 90 度角“向下看”条形码。其二,这样能确保条码图像的梯度区域被我们设计的简单条码探测器探测到。第二个假设为:我们的视频具备条形码的“特写”。这表明我们会把智能手机直接置于条形码的上方,而非将条形码放置在远离镜头的位置。我们把条形码从相机处移离得越远,我们那简单的条形码检测器就越难以成功。若你想要设计出一个更优良的条形码检测器,可去参考博客 1 和博客 2 的实现细节。

参考资料

[1] 参考链接

注意事项

如果您对 AI 方面的技术感兴趣,欢迎关注我的微信公众号“AI 产品汇”。如果您对自动驾驶技术感兴趣,欢迎关注我的微信公众号“AI 产品汇”。如果您对 AR 技术感兴趣,欢迎关注我的微信公众号“AI 产品汇”。如果您对 GPT 等技术感兴趣,欢迎关注我的微信公众号“AI 产品汇”。有问题可以在公众号中私聊我!

此博客为本人原创。若您对该博客感兴趣且想转载,可联系我(qq 邮箱:1575262785@qq.com),我会及时回复大家,感谢大家的关注。

个人能力有限,所以该博客或许存在诸多问题,期望大家能提出改进的意见。

如果您在阅读本博客时有不理解之处,希望您能联系我。我会及时回复您,与您交流想法和意见,谢谢。

关注公众号 AI 产品汇之后可以找我索取本文测试的图片。

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

27阅读

python教程大全集,python教程600集

2026年09月02日

26阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

22阅读