利用python识别图片中的条码及条码图片矫正和增强!

前言

这周和大家分享如何用python识别图像里的条码。用到的库可以是zbar。希望西瓜6辛苦码的代码不要被盗了。(zxing的话,我一直没有装好,等装好之后再写一篇)

具体步骤

前期准备

用opencv去读取图片,用pip进行安装。

PS:如有需要Python学习资料的小伙伴可以加点击下方链接自行获取

python免费学习资料以及群交流解答点击即可加入

 

pip install opencv-python
1

所用到的图片就是这个

使用pyzbar

windows的安装方法是

pip install pyzbar
1

而mac的话,最好用brew来安装。
(有可能直接就好,也有可能很麻烦)
装好之后就是读取图片,识别条码。
代码如下

import cv2
import pyzbar.pyzbar as pyzbar

image=cv2.imread("/Users/phoenix/Downloads/barcode.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
texts = pyzbar.decode(gray)
for text in texts:
    tt = text.data.decode("utf-8")
print(tt)
123456789

结果如图:

特殊情况处理(条码图片矫正和增强)

只以pyzbar举例

条码是颠倒的是否会影响识别?

不影响,单纯颠倒180度和90度是不会影响识别的。
我们把上一个图的颠倒180度,用颠倒后的图试一下

import cv2
import pyzbar.pyzbar as pyzbar
import numpy as np

image=cv2.imread("/Users/phoenix/Downloads/barcode_180.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
texts = pyzbar.decode(gray)
print(texts)
if texts==[]:
    print("未识别成功")
else:
    for text in texts:
        tt = text.data.decode("utf-8")
    print("识别成功")
    print(tt)
123456789101112131415

结果如图


90度的话也是同样可以成功的。但是其它角度就会GG。

条码是倾斜的是否会影响识别?

会的,但这种还比较好处理。
如图


这张图用上面的代码就会


解决的思路是把这个图片旋转回来,至于如何判断转多少度,可以通过opencv来处理。通过膨胀和腐蚀将其变为如图。


接着再用cv2.minAreaRect函数,这个函数会返回如下,


里面的第三个-45就是我们需要的角度。

综合起来的实现代码,我就放在下面了。(我自己写的,如果有帮到你,快点关注和赞)

import cv2
import pyzbar.pyzbar as pyzbar
import numpy as np

def barcode(gray):
    texts = pyzbar.decode(gray)
    if texts == []:
        angle = barcode_angle(gray)
        if angle < -45:
            angle = -90 - angle
        texts = bar(gray, angle)
    if texts == []:
        gray = np.uint8(np.clip((1.1 * gray + 10), 0, 255))
        angle = barcode_angle(gray)
        #西瓜6写的,转载需声明
        if angle < -45:
            angle = -90 - angle
        texts = bar(gray, angle)
    return texts

def bar(image, angle):
    gray = image
    #西瓜6写的,转载需声明
    bar = rotate_bound(gray, 0 - angle)
    roi = cv2.cvtColor(bar, cv2.COLOR_BGR2RGB)
    texts = pyzbar.decode(roi)
    return texts


def barcode_angle(image):
    gray = image
    #西瓜6写的,转载需声明
    ret, binary = cv2.threshold(gray, 220, 255, cv2.THRESH_BINARY_INV)
    kernel = np.ones((8, 8), np.uint8)
    dilation = cv2.dilate(binary, kernel, iterations=1)
    erosion = cv2.erode(dilation, kernel, iterations=1)
    erosion = cv2.erode(erosion, kernel, iterations=1)
    erosion = cv2.erode(erosion, kernel, iterations=1)
    
    contours, hierarchy = cv2.findContours(
        erosion, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    if len(contours) == 0:
        rect = [0, 0, 0]
    else:
        rect = cv2.minAreaRect(contours[0])
    return rect[2]

def rotate_bound(image, angle):
    (h, w) = image.shape[:2]
    (cX, cY) = (w // 2, h // 2)

    M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
    cos = np.abs(M[0, 0])
    sin = np.abs(M[0, 1])
    #西瓜6写的,转载需声明
    nW = int((h * sin) + (w * cos))
    nH = int((h * cos) + (w * sin))

    M[0, 2] += (nW / 2) - cX
    M[1, 2] += (nH / 2) - cY

    return cv2.warpAffine(image, M, (nW, nH))

image=cv2.imread("/Users/phoenix/Downloads/barcode_455.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
texts = barcode(gray)
print(texts)
if texts==[]:
    print("未识别成功")
else:
    for text in texts:
        tt = text.data.decode("utf-8")
    print("识别成功")
    print(tt)

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475

条码是模糊的是否会影响识别?

会的,处理方法就是传统的调对比度,锐化。。。。
不过这个只能解决部分部分,至于有的条码,微信可以扫,支付宝可以扫,但是我们识别不了,这个也不能怪库不好,这部分该放弃就放弃吧。

结束语

如果你想用python来解决图像里的条码识别问题,这篇文章肯定是可以帮到你的。有不懂的,可以评论出来,我每天都会看,看到也就会回复。所以麻烦关注,点赞加评论咯。

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值