今天我们将重构代码去检测视频中的条形码。

举个例子,下图是我实验的一个截图,我手持Modern Warfare 3,我们的程序能够顺利检测到其背面的条形码。

图1:使用Python和OpenCV检测视频流中的条形码

注意:非常感谢Jason的建议,他在上次的博客中留言道:要是能检测视频中的条形码将是很酷的事情。你说的很对,这确实很酷。

举个例子,假设我们12月26日这天正在电玩店工作。店外面排起了足有十个街区长的队伍,这些孩子正等着退货或是换货(显而易见,他们的父母或亲戚买错东西了)。

为了加快换货速度,我们就到队伍中间去一个一个去扫描他们的条形码。但是问题来了,激光扫描枪的线是连接到柜台上的电脑上的,队伍可有10个街区长,怎么都够不到。

既然这样,我有个计划:那我们可以用智能手机代替。

使用我们的iPhone(或者Android),带上摄像头,切换到录像模式,向着漫漫长队开工吧。

只要手机摄像头扫描到商品上的条形码,我们的APP就会检测到它的信息并及时传回到柜台。

听起来是不是太美好了,简直难以置信。

也许吧。毕竟,你也可以用激光扫描枪和无线连接来完成这项工作。况且稍后也会看到我们方法的局限性。

但是,我还是觉得这是一个关于使用OpenCV和Python检测条形码的好例子,该例展示了利用OpenCV函数来构建一个真实的应用。

不管怎样,继续往下看,看我们是怎么使用OpenCV和Python来检测视频中的条形码的。

使用Python和OpenCV在视频中实时监测条形码

这就是我们的方案,我们的视频条形码检测系统分成两个部分:

部件1:该模块检测图像中的条形码(本例中,既是视频中的帧图像)。上篇博客中我们已经实现了该功能,现在我们只需要简单修改一下代码即可

部件2:该模块的功能是读取视频源,然后调用条形码检测模块。

我们先讲解第一部分,单帧图像的条形码检测。

部件1:视频帧中的条形码检测

由于上篇博客中已经讲到图像中条形码的检测,这里我就不再熬述。

尽管这样,基于完整性考虑,我快速过一下这部分内容。打开一个新文件,取名simple_barcode_detection.py,开始编码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

# import the necessary packages

importnumpyasnp

importcv2

defdetect(image):

# convert the image to grayscale

gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)

# compute the Scharr gradient magnitude representation of the images

# in both the x and y direction

gradX=cv2.Sobel(gray,ddepth=cv2.cv.CV_32F,dx=1,dy=0,ksize=-1)

gradY=cv2.Sobel(gray,ddepth=cv2.cv.CV_32F,dx=0,dy=1,ksize=-1)

# subtract the y-gradient from the x-gradient

gradient=cv2.subtract(gradX,gradY)

gradient=cv2.convertScaleAbs(gradient)

# blur and threshold the image

blurred=cv2.blur(gradient,(9,9))

(_,thresh)=cv2.threshold(blurred,225,255,cv2.THRESH_BINARY)

# construct a closing kernel and apply it to the thresholded image

kernel=cv2.getStructuringElement(cv2.MORPH_RECT,(21,7))

closed=cv2.morphologyEx(thresh,cv2.MORPH_CLOSE,kernel)

# perform a series of erosions and dilations

closed=cv2.erode(closed,None,iterations=4)

closed=cv2.dilate(closed,None,iterations=4)

# find the contours in the thresholded image

(cnts,_)=cv2.findContours(closed.copy(),cv2.RETR_EXTERNAL,

cv2.CHAIN_APPROX_SIMPLE)

# if no contours were found, return None

iflen(cnts)==0:

returnNone

# otherwise, sort the contours by area and compute the rotated

# bounding box of the largest contour

c=sorted(cnts,key=cv2.contourArea,reverse=True)[0]

rect=cv2.minAreaRect(c)

box=np.int0(cv2.cv.BoxPoints(rect))

# return the bounding box of the barcode

returnbox

如果你看过之前的博客,那么这段关于在图像中检测条形码的代码将非常熟悉。

第一件事就是导入NumPy库来做数值计算,cv2来调用OpenCV。

第5行定义的函数带1个参数,就是需要检测条形码的图像。

第7行将图像转换为灰度图像,9-16行检测图像中具有水平梯度高和垂直梯度低的区域(想了解更多,请参看前面条形码检测的博客)。

19和20行分别模糊图像和二值化图像,方便后续23-28行的形态学处理。形态学操作用来检出条形码的矩形区域,忽略其他区域。

现在我们已经有了条形码的矩形区域,接下来在30-31行就是找出其轮廓。

如果没有找到轮廓,那么就认为没有条形码(35和36行)。

如果找到了轮廓,在40行我们就对轮廓进行排序(轮廓按面积大小降序排列)。这里,我们同样假设面积最大的轮廓就是条形码的位置。

最后,我们拿到这个轮廓,然后计算该轮廓的矩形包络(41和42行)。然后45行就返回该包络的x,y坐标,意即条形码的位置。

现在,我们这个简单的条形码检测就告完成,步入第二部分,图像获取,然后整合第一部分。

部件2:访问摄像头,检测视频中的条形码

我们开始构建一个驱动接口以便后面检测视频中的条形码。打开并新建一个文件,取名detect_barcode.py,开始构建第二个部件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

# import the necessary packages

frompyimagesearchimportsimple_barcode_detection

importargparse

importcv2

# construct the argument parse and parse the arguments

ap=argparse.ArgumentParser()

ap.add_argument("-v","--video",help="path to the (optional) video file")

args=vars(ap.parse_args())

# if the video path was not supplied, grab the reference to the

# camera

ifnotargs.get("video",False):

camera=cv2.VideoCapture(0)

# otherwise, load the video

else:

camera=cv2.VideoCapture(args["video"])

我们开始也是导入我们需要的库。出于方便管理的目的,我们将simple_barcode_detection函数放到pyimagesearch模块中,并在此导入。然后我们导入argparse来解析命令,导入cv2来调用OpenCV的函数。

6-9行解析我们的命令行参数。我们设置了一个可选项,–video,该选项指定需要检测条形码的视频文件路径。

注意:这个切换选项对于运行源代码提供的例子视频还是很有用的。忽略这个选项默认就是用笔记本或是台式机上的摄像头。

13-18行获取一个camera引用,如果没有–video选项,那么就获取一个webcam;反之就活去一个视频文件句柄(17-18行)。

设置完成后,我们就可以开始加载我们的条形码检测模块了。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

# keep looping over the frames

whileTrue:

# grab the current frame

(grabbed,frame)=camera.read()

# check to see if we have reached the end of the

# video

ifnotgrabbed:

break

# detect the barcode in the image

box=simple_barcode_detection.detect(frame)

# if a barcode was found, draw a bounding box on the frame

cv2.drawContours(frame,[box],-1,(0,255,0),2)

# show the frame and record if the user presses a key

cv2.imshow("Frame",frame)

key=cv2.waitKey(1)&0xFF

# if the 'q' key is pressed, stop the loop

ifkey==ord("q"):

break

# cleanup the camera and close any open windows

camera.release()

cv2.destroyAllWindows()

第2行我们开始循环抓取视频中的图像帧,直到抓取完视频中的图像或者说我们按下q键然后退出循环。

第5行中,我们访问camera。返回值是2-tuple.其一是boolean值,表示是否抓取成功(从摄像头或者视频文件)。frame这是实际抓取到的图像数据。

如果抓取失败(例如到了视频文件尾部),11和12行就退出循环。

一旦抓取到图像帧,在16行我们就利用条形码检测模块检测图像中的条形码,返回外接矩形范围。

我们将最终的包络区域绘制在图像中(20行),最后显示到屏幕上(23和24行).

最后,29和30行则检测q键是否按下,按下就退出循环。32和33行就进行camera对象的清理操作。

如你所见,我们的脚本还是比较简洁的。开始运行我们的代码,看看结果如何。

成功检测视频中的条形码

我们试一些例子,打开终端,输入如下指令:

1

$pythondetect_barcode.py--videovideo/video_games.mov

本博客的开始部分就展示了我们脚本的输出结果。下面则是三个成功的条形码检测视频截图。

图2:在Xbox视频游戏流中,成功检测条形码

我们看一个在衣服优惠券上检测的例子:

1

$pythondetect_barcode.py--videovideo/coupon.mov

如下是一个视频流截图:

图3:使用Python和OpenCV成功检测条形码的示例

完整视频输出:

当然,如我之前所说,我们的方法只在很好的条件下才有效(稍后会详述该方法的缺点和限制)

这就是一个条形码检测失败的例子。

图4:一个失败的例子。条形码离摄像头太远了

该种情形下,条形码离摄像头太远,图像中也有太多的干扰和噪声,例如视频游戏盒子上有很多的大块的文本区。

这个也是个失败案例,我只是想开个玩笑而已。

图5:我的耳朵当然不是条形码

再一次说,我们这只是一个很简单的解决办法,并不适用于所有情况。虽说不是一个健壮的解决方案,但如果能满足下述条件的情况下,简单的图像处理还是能提供让人惊讶的够好的结果。

限制条件和缺点

就如博文中见到的,我们的方法在一定假设条件下还是能顺利检测到视频中的条形码。

第一个假设:我们的相机以90度的静态视角来观察这个条形码。以使条形码区域的图像梯度能够被条形码检测器检测到。

第二个假设:我们的视频或者摄像头是近距离查看条形码,也就是我们拿着智能手机直接对着条形码的上面,而不是远离摄像头。条形码离相机越远,成功检测的概率就越小。

那么怎样改进我们的条形码检测器呢?

好问题

Christoph Oberhofer 提供了一篇很好的综述,关于在QuaggaJS中如何实现条形码的鲁棒检测。 Tomasz Malisiewicz也写了一篇很好的文章,关于如何利用他的VMX中的机器学习算法来训练出一个条形码检测器。如果你想更近一步了解这些内容,请一定要看这些文章。

总结

基于之前在图像中检测条形码的程序,本文中我们将代码分为两部分:

一个部件就是检测视频帧的条形码

另一个则是访问视频源(摄像头或者视频文件)

然后使用条形码检测模块检测视频中的条形码。

我们的方法有如下假设:

第一个假设就是我们摄像头的向下看的静态视角为90度。

第二个假设是我们会拉近看图像中的条形码,且图像中没有其他干扰物或噪声。

事实上,能否满足这些假设全取决于你的实际应用场景。

至少,我想通过这篇博文给你说明的是一些基本的图像处理技术,以及如何采用Python和OpenCV,实现这些图像处理技术来构成一个简单的条形码检测器。

python 扫描枪_使用Python和OpenCV在视频中实时监测条形码相关推荐

  1. 使用Python,OpenCV在视频中进行实时条形码检测

    使用Python,OpenCV在视频中进行实时条形码检测 1. 步骤 2. 适用场景及优化 3. 总结 4. 源码 参考 上一篇博客介绍了如何检测和查找图像中的条形码.这篇博客将进行一些优化以检测实时 ...

  2. python 时间序列预测_使用Python进行动手时间序列预测

    python 时间序列预测 Time series analysis is the endeavor of extracting meaningful summary and statistical ...

  3. python 概率分布模型_使用python的概率模型进行公司估值

    python 概率分布模型 Note from Towards Data Science's editors: While we allow independent authors to publis ...

  4. 实现原理 扫描枪_扫描枪的工作原理

    原标题:扫描枪的工作原理 随着条形码软件在各个行业中的应用,条码打印机和扫描枪越来越多出现在人们的视线中, 今天让我们来了解下扫描枪的详细信息. 扫描枪的常用接口类型有以下三种: (1)SCSI(小型 ...

  5. OpenCV实现视频中目标的跟踪

    meanshift实现视频跟踪 import matplotlib.pyplot as plt import cv2 as cv import numpy as np plt.rcParams['fo ...

  6. python图像计数_计算机视觉:利用OpenCV和Python进行车辆计数详细步骤

    本教程我将分享几个简单步骤解释如何使用OpenCV进行Python对象计数. 需要安装一些软件: Python 3 OpennCV 1.了解Opencv从摄像头获得视频的Python脚本import ...

  7. cv2 python 获取斑马线_基于python的opencv图像处理实现对斑马线的检测示例

    基本思路 斑马线检测通过opencv图像处理来进行灰度值转换.高斯滤波去噪.阈值处理.腐蚀和膨胀后对图像进行轮廓检测,通过判断车辆和行人的位置,以及他们之间的距离信息,当车速到超过一定阈值时并且与行人 ...

  8. python中提取几列_自己录制的公开课视频中提取字幕(python+opencv+Tesseract-OCR)

    最近在mooc上看了一个公开课:职场英语,用来学习在找工作时或者工作中用到的英语交流技巧,非常不错.由于自己听力不是很好,有的字幕中的单词不认识,并且想记下来便于以后学习.所以想把公开课中的字幕都记录 ...

  9. python图像识别马路_使用Python和OpenCV在道路上找到车道线

    识别道路上的车道是所有司机的共同任务,以确保车辆在驾驶时处于车道限制之内,并减少因越过车道而与其他车辆发生碰撞的机会. 对自动驾驶汽车来说,这同样也是一项关键任务.事实证明,使用计算机视觉技术识别道路 ...

  10. python画狗头_人工智能python+dlib+opencv技术10分钟实现抖音人脸变狗头详细图文教程和完整项目代码...

    效果展示 动态效果 静态效果 未完待续... 素材 项目讲解.代码和素材 开发环境 win7sp1 python                 3.6.3 dlib                 ...

最新文章

  1. java环境配置好了还不行,java配置环境java不行
  2. 利用usb远程控制linux,Linux编程控制硬件(5) ---- 操作USB手柄
  3. string数组批量转换成Int数组
  4. Spring集成基础知识
  5. Android 可开关式顶部下拉view
  6. 前沿 | 谷歌用深度学习进行深度预测
  7. C#线程系列讲座(5):同步技术之Monitor
  8. 如何将namedtuples序列化为JSON
  9. jQuery中文文档
  10. c语言课设代写一般多少钱_海南彩礼钱一般给多少 海南娶媳妇要多少钱
  11. 在线支付功能的设计及其实现
  12. 相机标定——标定图片拍摄规范
  13. 应聘PHP有面试题吗,php应聘面试题
  14. 《惢客创业日记》2021.08.28-31(周六)一错即否、一善俱荣(三)
  15. mezzanine timezone 的问题
  16. 汇编学习 安装DOSBOX及debug.exe教程
  17. KEIL5 头文件路径设置摸索和总结
  18. 计算机音乐小二郎,小二郎_儿童歌曲_单曲在线试听_酷我音乐
  19. 联想计算机电源维修,台式联想电脑,主机电源灯不亮是怎么回事,应该怎么维修...
  20. 嵌入式 linux 蓝牙 C开发

热门文章

  1. 计算机考研复试笔试题库,苏州大学计算机考研复试真题和复试参考书目
  2. spark入门demo
  3. 黑苹果 hackintosh 声卡驱动
  4. ubuntu局域网服务器搭建网站,ubuntu搭建局域网dns服务器
  5. arm架构安装rxtx_树莓派JAVA开发串口(RXTX)和GPIO(pi4j)
  6. Geometry-enhanced molecular representation learning for property prediction|GeoGNN|将几何增强分子表示用于分子性质预测
  7. 2.ISIS协议原理
  8. 省市县三级联动插件distpicker
  9. java技术管理的简历_基于javaweb个人简历生成及管理系统.doc
  10. 企业级POS收银系统源码(客户端+后台)