python+OpenCV检测条形码

        今天看到一篇关于条形码检测的文章,还是存在一些问题的,昨天我陪朋友去取快递的时候,看到了关于条形码检测在现实场景中的应用,于是,便想着实现一波,并且对程序中的一些问题做了一些修改。

首先要确定调用的包/库的版本,这是在我电脑上程序的运行环境(在今后的文章中,我会特别注意版本问题,这个非常重要):

  • python3.6 + win 10
  • numpy 1.16.2
  • imutils 0.5.2
  • opencv 4.1.0
图片来源于百度

 

一、导入需要用到的包/库

import numpy as np
import imutils
import cv2

二、转化为灰度图

一般对图像的处理操作都是在灰度图的基础上进行的。

image = cv2.imread('D:\image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

 

三、使用Scharr算子进行边缘检测

        条形码一般具有以下特点:矩形形状,条带是黑色,背景为白色,而且黑白相间。这就导致条形码区域光暗变化明显,这对于Scharr算子非常合适,因为Scharr算子对于图像梯度的变化更加敏感,更有利于获取条形码的特征。

想要了解更多的边缘检测算法,可以查看我的这篇博客:https://blog.csdn.net/qq_40962368/article/details/81416954

ddepth = cv2.CV_32F if imutils.is_cv2() else cv2.CV_32F
gradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1)
gradient = cv2.subtract(gradX,gradY)
gradient = cv2.convertScaleAbs(gradient)

 

四、去除噪声

        (1)模糊与阈值化处理

            通过均值滤波对图像进行模糊处理,通过阈值化处理将图像转化为二值图像。以此来去除图像中的绝大部分噪声。cv2.threshold函数的第二个参数是为阈值化处理所设置的阈值,为了尽可能的去除噪声,所以,尽量将此值设置的大一些,但不能过大,以免影响条形码特征本身。

关于更多的OpenCV中阈值分割的方法,可以查看我的这篇博客:https://blog.csdn.net/qq_40962368/article/details/80917250

blurred = cv2.blur(gradient,(9, 9))
(_, thresh) = cv2.threshold(blurred, 231, 255, cv2.THRESH_BINARY)

 

         (2)形态学处理

            通过形态学处理,去除图像细小的噪声斑点。使用cv2.getStructuringElement函数定义结构元素,经过一个开运算,再经过四次腐蚀与四次膨胀,更好的去除噪声。

关于形态学的操作一些方法,可以查看我的这篇博客:https://blog.csdn.net/qq_40962368/article/details/81276820

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)

 

五、确定检测轮廓,画出检测框

        OpenCV中提供了识别图像区域的函数,非常好用,找相应的区域,根据区域大小进行排序,保留最大的区域,该区域就是我们要找的条形码区域。计算该轮廓的旋转边界框,确定位置信息,画出检测框。

cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]

rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect)
box = np.int0(box)

cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

总结:从检测结果来看,在特定的应用场景下,检测效果还是挺好的,但不适合应用于所有的应用场景,但我们可以从条形码的检测过程可以看出解决这类问题的一般想法,为以后解决类似的问题提供一种比较可靠的思路。

 

参考网址:https://www.pyimagesearch.com/2014/11/24detecting-barcodes-images-python-opencv/

  • 14
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值