20230223-基于pyzbar识别条形码并标注示例

关注公众号 `N学无止界` 获取更多

目录:

一、环境说明

二、pyzbar简介

三、示例代码

四、思考总结

一、环境说明


本机环境:windows10 操作系统
使用工具:Visual Studio Code 1.74.3(user setup)
Python版本:Python --version
            Python 3.9.16
pip版本: pip --version
         pip 22.3.1 from C:\Users\Jack\.conda\envs\py\lib\site-packages\pip (python 3.9)
opencv版本:opencv-contrib-python 4.7.0.68 (主要用于图片的读取和展示,可以用其他库代替)
pyzbar版本:pyzbar                0.1.9 (主库,本示例主要介绍)

备注:
安装Python库命令: pip install [库名]=[版本号]  
    比如:  pip install pyzbar==0.1.9
下载缓慢可以尝试利用下面命令更新国内镜像仓库
    pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
    pip config set install.trusted-host https://pypi.tuna.tsinghua.edu.cn 

二、pyzbar简介

官方介绍: pyzbar · PyPI

安装命令: pip install pyzbar

官方示例程序:

The decode function accepts instances of PIL.Image.


>>> from pyzbar.pyzbar import decode
>>> from PIL import Image
>>> decode(Image.open('pyzbar/tests/code128.png'))
[
    Decoded(
        data=b'Foramenifera', type='CODE128',
        rect=Rect(left=37, top=550, width=324, height=76),
        polygon=[
            Point(x=37, y=551), Point(x=37, y=625), Point(x=361, y=626),
            Point(x=361, y=550)
        ],
        orientation="UP",
        quality=77
    )
    Decoded(
        data=b'Rana temporaria', type='CODE128',
        rect=Rect(left=4, top=0, width=390, height=76),
        polygon=[
            Point(x=4, y=1), Point(x=4, y=75), Point(x=394, y=76),
            Point(x=394, y=0)
        ],
        orientation="UP",
        quality=77
    )
]

It also accepts instances of numpy.ndarray, which might come from loading images using OpenCV.


>>> import cv2
>>> decode(cv2.imread('pyzbar/tests/code128.png'))
[
    Decoded(
        data=b'Foramenifera', type='CODE128',
        rect=Rect(left=37, top=550, width=324, height=76),
        polygon=[
            Point(x=37, y=551), Point(x=37, y=625), Point(x=361, y=626),
            Point(x=361, y=550)
        ],
        orientation="UP",
        quality=77
    )
    Decoded(
        data=b'Rana temporaria', type='CODE128',
        rect=Rect(left=4, top=0, width=390, height=76),
        polygon=[
            Point(x=4, y=1), Point(x=4, y=75), Point(x=394, y=76),
            Point(x=394, y=0)
        ],
        orientation="UP",
        quality=77
    )
]

You can also provide a tuple (pixels, width, height), where the image data is eight bits-per-pixel.


>>> image = cv2.imread('pyzbar/tests/code128.png')
>>> height, width = image.shape[:2]

>>> # 8 bpp by considering just the blue channel
>>> decode((image[:, :, 0].astype('uint8').tobytes(), width, height))
[
    Decoded(
        data=b'Foramenifera', type='CODE128',
        rect=Rect(left=37, top=550, width=324, height=76),
        polygon=[
            Point(x=37, y=551), Point(x=37, y=625), Point(x=361, y=626),
            Point(x=361, y=550)
        ],
        orientation="UP",
        quality=77
    )
    Decoded(
        data=b'Rana temporaria', type='CODE128',
        rect=Rect(left=4, top=0, width=390, height=76),
        polygon=[
            Point(x=4, y=1), Point(x=4, y=75), Point(x=394, y=76),
            Point(x=394, y=0)
        ],
        orientation="UP",
        quality=77
    )
]

>>> # 8 bpp by converting image to greyscale
>>> grey = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
>>> decode((grey.tobytes(), width, height))
[
    Decoded(
        data=b'Foramenifera', type='CODE128',
        rect=Rect(left=37, top=550, width=324, height=76),
        polygon=[
            Point(x=37, y=551), Point(x=37, y=625), Point(x=361, y=626),
            Point(x=361, y=550)
        ],
        orientation="UP",
        quality=77
    )
    Decoded(
        data=b'Rana temporaria', type='CODE128',
        rect=Rect(left=4, top=0, width=390, height=76),
        polygon=[
            Point(x=4, y=1), Point(x=4, y=75), Point(x=394, y=76),
            Point(x=394, y=0)
        ],
        orientation="UP",
        quality=77
    )
]

>>> # If you don't provide 8 bpp
>>> decode((image.tobytes(), width, height))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/lawh/projects/pyzbar/pyzbar/pyzbar.py", line 102, in decode
    raise PyZbarError('Unsupported bits-per-pixel [{0}]'.format(bpp))
pyzbar.pyzbar_error.PyZbarError: Unsupported bits-per-pixel [24]

The default behaviour is to decode all symbol types. You can look for just your symbol types


>>> from pyzbar.pyzbar import ZBarSymbol
>>> # Look for just qrcode
>>> decode(Image.open('pyzbar/tests/qrcode.png'), symbols=[ZBarSymbol.QRCODE])
[
    Decoded(
        data=b'Thalassiodracon', type='QRCODE',
        rect=Rect(left=27, top=27, width=145, height=145),
        polygon=[
            Point(x=27, y=27), Point(x=27, y=172), Point(x=172, y=172),
            Point(x=172, y=27)
        ],
        orientation="UP",
        quality=1
    )
]


>>> # If we look for just code128, the qrcodes in the image will not be detected
>>> decode(Image.open('pyzbar/tests/qrcode.png'), symbols=[ZBarSymbol.CODE128])
[]

三、示例代码

说明:本示例识别出条形码,并标注出来进行展示或者返回坐标信息

待识别图片:

程序代码:


# -*- coding: utf-8 -*-

# __ author:Jack
# date: 2023-02-23

import cv2
import pyzbar.pyzbar as pyzbar

def zbar_demo():
    img = cv2.imread(r'F:\tmp\all_code.png')
    zbars= pyzbar.decode(img)

    order = 1
    if zbars :
        for item in zbars:
            txt = item.data.decode('utf-8')

            x, y, w, h = item.rect
            cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

            txt_show = "{0}  {1}  {2}-{3}".format(str(order),txt,x,y)
            cv2.putText(img, txt_show, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX,1, (0, 0, 125), 2)
            order=order+1
            print(item)
    cv2.imshow('zbar_demo', img)
    cv2.waitKey(0)

if __name__=='__main__':
    zbar_demo()

识别后结果:

上述print(item)内容输出的结果:

Decoded(data=b'QR Code\xc3\x82\xc3\xab\xc3\x8a\xc3\x87\xc3\x93\xc3\x89\xc3\x88\xc3\x95\xc2\xb1\xc2\xbeDenso\xc2\xb9\xc2\xab\xc3\x8b\xc2\xbe\xc3\x93\xc3\x9a1994\xc3\x84\xc3\xaa9\xc3\x94\xc3\x82\xc3\x91\xc3\x90\xc3\x96\xc3\x86\xc2\xb5\xc3\x84\xc3\x92\xc2\xbb\xc3\x96\xc3\x96\xc2\xbe\xc3\x98\xc3\x95\xc3\xb3\xc2\xb6\xc3\xbe\xc3\x8e\xc2\xac\xc3\x82\xc3\xab\xc2\xb7\xc3\xbb\xc2\xba\xc3\x85\xc2\xa3\xc2\xac\xc3\x8b\xc3\xbc\xc2\xb3\xc3\xbd\xc2\xbe\xc3\x9f\xc3\x93\xc3\x90\xc3\x92\xc2\xbb\xc3\x8e\xc2\xac\xc3\x8c\xc3\xb5\xc3\x82\xc3\xab\xc2\xbc\xc2\xb0\xc3\x86\xc3\xa4\xc3\x8b\xc3\xbc\xc2\xb6\xc3\xbe\xc3\x8e\xc2\xac\xc3\x8c\xc3\xb5\xc3\x82\xc3\xab\xc3\x8b\xc3\xb9\xc2\xbe\xc3\x9f\xc3\x93\xc3\x90\xc2\xb5\xc3\x84\xc3\x90\xc3\x85\xc3\x8f\xc2\xa2\xc3\x88\xc3\x9d\xc3\x81\xc2\xbf\xc2\xb4\xc3\xb3\xc2\xa1\xc2\xa2\xc2\xbf\xc3\x89\xc2\xbf\xc2\xbf\xc3\x90\xc3\x94\xc2\xb8\xc3\x9f\xc2\xa1\xc2\xa2\xc2\xbf\xc3\x89\xc2\xb1\xc3\xad\xc3\x8a\xc2\xbe\xc2\xba\xc2\xba\xc3\x97\xc3\x96\xc2\xbc\xc2\xb0\xc3\x8d\xc2\xbc\xc3\x8f\xc3\xb3\xc2\xb6\xc3\xa0\xc3\x96\xc3\x96\xc3\x8e\xc3\x84\xc3\x97\xc3\x96\xc3\x90\xc3\x85\xc3\x8f\xc2\xa2\xc2\xa1\xc2\xa2\xc2\xb1\xc2\xa3\xc3\x83\xc3\x9c\xc2\xb7\xc3\x80\xc3\x8e\xc2\xb1\xc3\x90\xc3\x94\xc3\x87\xc2\xbf\xc2\xb5\xc3\x88\xc3\x93\xc3\x85\xc2\xb5\xc3\xa3\xc3\x8d\xc3\xa2\xc2\xa3\xc2\xac\xc2\xbb\xc2\xb9\xc2\xbe\xc3\x9f\xc3\x93\xc3\x90\xc3\x88\xc3\xa7\xc3\x8f\xc3\x82\xc3\x96\xc3\xb7\xc3\x92\xc2\xaa\xc3\x8c\xc3\x98\xc2\xb5\xc3\xa3\xc2\xa3\xc2\xba', type='QRCODE', rect=Rect(left=1374, top=511, width=162, height=163), polygon=[Point(x=1374, y=511), Point(x=1374, y=673), Point(x=1536, y=674), Point(x=1535, y=511)], quality=1, orientation='UP')
Decoded(data=b'Aux(124)-TR', type='CODE128', rect=Rect(left=550, top=599, width=287, height=71), polygon=[Point(x=550, y=599), Point(x=550, y=669), Point(x=837, y=670), Point(x=837, y=600)], quality=72, orientation='UP')
Decoded(data=b'A000800A', type='CODABAR', rect=Rect(left=53, top=551, width=292, height=104), polygon=[Point(x=53, y=551), Point(x=53, y=655), Point(x=345, y=652), Point(x=345, y=554)], quality=101, orientation='UP')Decoded(data=b'123ABC', type='CODE39', rect=Rect(left=61, top=418, width=294, height=45), polygon=[Point(x=61, y=419), Point(x=61, y=463), Point(x=355, y=458), Point(x=355, y=418)], quality=44, orientation='UP')     
Decoded(data=b'BJ100080', type='CODE93', rect=Rect(left=535, top=381, width=290, height=94), polygon=[Point(x=535, y=381), Point(x=535, y=475), Point(x=825, y=474), Point(x=825, y=382)], quality=95, orientation='UP')Decoded(data=b'69012341', type='EAN8', rect=Rect(left=169, top=227, width=201, height=90), polygon=[Point(x=169, y=227), Point(x=169, y=317), Point(x=265, y=317), Point(x=370, y=316), Point(x=370, y=228)], quality=144, orientation='UP')
Decoded(data=b'0089000006007', type='EAN13', rect=Rect(left=681, top=207, width=147, height=83), polygon=[Point(x=681, y=207), Point(x=681, y=289), Point(x=828, y=290), Point(x=828, y=212)], quality=82, orientation='UP')
Decoded(data=b'6901234567892', type='EAN13', rect=Rect(left=151, top=32, width=264, height=90), polygon=[Point(x=151, y=33), Point(x=151, y=121), Point(x=287, y=122), Point(x=415, y=122), Point(x=415, y=32)], quality=144, orientation='UP')
Decoded(data=b'0089600124569', type='EAN13', rect=Rect(left=635, top=16, width=253, height=84), polygon=[Point(x=635, y=17), Point(x=635, y=99), Point(x=888, y=100), Point(x=888, y=16)], quality=132, orientation='UP')
Decoded(data=b'1234567890', type='I25', rect=Rect(left=1051, top=0, width=292, height=101), polygon=[Point(x=1051, y=1), Point(x=1051, y=101), Point(x=1343, y=100), Point(x=1343, y=0)], quality=102, orientation='UP')

四、思考总结

利用pyzbar识别出来的条形码由于有些条形码规则未被pyzbar收录,或者条形码图片变形已经失去条形码具备信息无法识别,此时如果要增加识别率进步可能的增加识别条形码可以通过其他模式(比如OCR识别和一定的规则)来进一步识别未识别到的然后去并集。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_software

感谢打赏,我努力提供优质内容~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值