怎样用Python识别条形码?

怎样用Python识别条形码?最近一位热心的网友找到宋宋,想做一个条形码或者二维码的识别系统。现在,他在北京的某知名大型连锁超市,需要通过Python识别条形码,进行快速的商品库存录入。如果已经存在的则不进行录入。不知Python能否实现?所以趁此机会我们给大家介绍下OpenCV和pyzbar。废话不多说,进入正题……条码在生活中随处可见,其可分为三类:一维条码、二维条码、三维条码一维条码:我们平时习惯称为条形码。条形码是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

最近一位热心的网友找到宋宋,想做一个条形码或者二维码的识别系统。

现在,他在北京的某知名大型连锁超市,需要通过Python识别条形码,进行快速的商品库存录入。如果已经存在的则不进行录入。不知Python能否实现?所以趁此机会我们给大家介绍下OpenCV和pyzbar。

废话不多说,进入正题……

条码在生活中随处可见,其可分为三类:一维条码、二维条码、三维条码

一维条码:

我们平时习惯称为条形码。条形码是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符。常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案。

Jetbrains全家桶1年46,售后保障稳定

我们平时习惯称为条形码。条形码是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符。常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案。

二维条码简称为二维码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。

三维条码:

三维条码具有更大的信息容量、相同的识别便易性和较好的安全性。三维码的主要特征在于利用色彩或灰度(或称黑密度)表示不同的数据并进行编码。

其实Python的条码扫描库,一直都有一个很是出名,那就是zbar,但此库虽然牛,却已经停止维护了,如果是python3,则不能使用zbar库了,现在对于我们Python3来说使用比较多的是:pyzbar

tips:宋宋老师的电脑是Mac系统的,单纯只安装pyzbar是有问题的。需要安装系统支持的zbar,使用:brew install zbar

然后再安装pyzbar,就没有问题啦!

pip install pyzbar

如果需要摄像头识别条形码或者二维码需要安装opencv和PIL,OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。OpenCV-Python是OpenCV的Python的API接口,它拥有OpenCV C++ API的功能,同时也拥有Python语言的特性,可以做到跨平台使用。

pip3 install opencv-python

步骤1:

使用opencv2,初始化摄像头信息,调整摄像头识别图像的width和height。

import cv2

capture = cv2.VideoCapture(0)

# 摄像头设置,
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
capture.set(cv2.CAP_PROP_EXPOSURE, 0.1)

步骤2:

测试cv2是否可以,调用摄像头识别图像,按esc退出

while True:
    # 读取摄像头中的图像,ok为是否读取成功的判断参数
    ret,img = capture.read()
    cv2.imshow('frame', img)
    k = cv2.waitKey(1)
    if k == 27:    # 'ESC'关闭
        break

步骤3:

import cv2
import csv
import pyzbar.pyzbar as pyzbar

barcodeData1 = ''

found = set()
capture = cv2.VideoCapture(0)

# 摄像头设置
capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)
capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
capture.set(cv2.CAP_PROP_EXPOSURE, 0.1)


while True:
    # 读取摄像头中的图像,ok为是否读取成功的判断参数
    ret, frame = capture.read()
    # 转为灰度图像
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    barcodes = pyzbar.decode(gray)
    print(barcodes)

如果识别出来条形码信息则打印如下:

[Decoded(data=b'9787545152210', type='EAN13', rect=Rect(left=677, top=116, width=195, height=136), polygon=[Point(x=677, y=239), Point(x=677, y=249), Point(x=771, y=251), Point(x=871, y=252), Point(x=872, y=118), Point(x=872, y=116), Point(x=678, y=117)])]

上面的信息包含了data即条形码的值,还有就是Rect矩形区域即识别出的条形码的区域,以及识别的一些像素点。

如果没有识别出条形码信息,比如宋宋一直在摄像头前面,哈哈哈我的脸上没有条形码,则打印出来的是空列表[ ]。

步骤4

上面?代码中的barcodes返回的是一个列表信息,我们可以对列表信息进行遍历。获取条形码值,type类型和矩形区域。并使用cv2将上图所示的矩形绘制出来。

    for barcode in barcodes:
        # 提取条形码的边界框的位置
        (x, y, w, h) = barcode.rect
        # 画出图像中条形码的边界框
        cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)

步骤5

data=b’9787545152210’是字节对象,此时我们需要将字节对象转成字符串。

        # 条形码数据为字节对象,所以如果我们想在输出图像上
        # 画出来,就需要先将它转换成字符串
        barcodeData = barcode.data.decode("utf-8")
        barcodeType = barcode.type

步骤6

读取商品信息表,判断识别出的条形码信息,是否在商品表中,为了避免扫描重复多次识别。使用了集合去重复条形码信息。

code_set = set() # 存放条形码的集合    # 避免重复读取        if barcodeData not in code_set:            with open('shopping.csv', 'r') as rs:                reader = csv.reader(rs)                # 遍历超市库存文件                for line in reader:                    if barcodeData in line:  # 说明超市有这个商品                        print(f'本超市存在此商品,名称:{line[1]},价格:{line[3]}')                        break                    else:                        pass        else:            pass        code_set.add(barcodeData)

步骤7

打开摄像头,如果按键是ESC则退出,识别系统

    cv2.imshow('qrcode+barcode', frame)    k = cv2.waitKey(1)    if k == 27:        breakcv2.destroyAllWindows()

完整代码:

import cv2import csvimport pyzbar.pyzbar as pyzbarbarcodeData1 = ''code_set = set()capture = cv2.VideoCapture(0)# 摄像头设置capture.set(cv2.CAP_PROP_FRAME_WIDTH, 1024)capture.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)capture.set(cv2.CAP_PROP_EXPOSURE, 0.1)while True:    # 读取摄像头中的图像,ok为是否读取成功的判断参数    ret, frame = capture.read()    # 转为灰度图像    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)    barcodes = pyzbar.decode(gray)    print(barcodes)    for barcode in barcodes:        # 提取条形码的边界框的位置        # 画出图像中条形码的边界框        (x, y, w, h) = barcode.rect        cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 0), 2)        # 条形码数据为字节对象,所以如果我们想在输出图像上        # 画出来,就需要先将它转换成字符串        barcodeData = barcode.data.decode("utf-8")        barcodeType = barcode.type        # print(barcodeData)        # 判断多次扫描一个条形码,只打印一次        if barcodeData == '' or barcodeData != barcodeData1:            barcodeData1 = barcodeData            print("Recognize result>>> type: {0}  content: {1}".format(barcodeType, barcodeData))        else:            pass        # 避免重复读取        if barcodeData not in code_set:            with open('shopping.csv', 'r') as rs:                reader = csv.reader(rs)                # 遍历超市库存文件                for line in reader:                     if barcodeData in line:  # 说明超市有这个商品                        print(f'本超市存在此商品,名称:{line[1]},价格:{line[3]}')                        break                    else:                        pass        else:            pass        code_set.add(barcodeData)    cv2.imshow('qrcode+barcode', frame)    k = cv2.waitKey(1)    if k == 27:        breakcv2.destroyAllWindows()

如果有什么问题,可以及时给宋宋老师留言哦!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/206793.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 深入学习Arduino u8g2 OLED库,一篇就够

    深入学习Arduino u8g2 OLED库,一篇就够1.前言    最近博主听到QQ群里面问得比较多的问题:    “博哥,有玩过OLED吗?”    “博哥,有试过在ESP8266上调成功过SSD1306吗?”    “博哥,OLED上显示天气信息怎么弄?”    …    诸如此类的问题,在博主看来,无非都是对OLED库用法的不熟悉甚至不了解。ArduinoOLED库众多,博主也曾经介绍过一款《博哥OLED系列》-玩转SSD1…

    2022年4月18日
    59
  • stp常见故障解决_解决端口占用问题

    stp常见故障解决_解决端口占用问题STP故障01-STP端口问题

    2022年4月21日
    139
  • Linux内核版本_linux最新版本是多少

    Linux内核版本_linux最新版本是多少Linux版本linux版本分为两类:内核版本:免费的,它只是操作系统的核心,负责控制硬件、管理文件系统、程序进程等,并不给用户提供各种工具和应用软件; 发行版本:不一定免费,出了操作系统核心外,还包含一套强大的软件,例如:C/C++编译器和库等1、内核版本:1.1)内核版本命名:Linux内核版本号由3组数字组成:第一个组数字.第二组数字.第三组数字第一个组数字:目前发布的内核主版本。 第二个组数字:偶数表示稳定版本;奇数表示开发中版本。 第三个组数字:错误修补的次数。可以使

    2022年8月23日
    9
  • minicom指令_minicom使用

    minicom指令_minicom使用Linux下的Minicom的功能与Windows下的超级终端功能相似,适于在linux通过超级终端对嵌入式设备的管理以及对嵌入操作系统的升级。1.启动minicom以root权限登录系统使用命令:minicom–s则minicom启动,出现配置界面。2.设置serialportsetup使用down箭头选择serialportsetup,出现具体各选项的配置:3.选择Save…

    2022年4月28日
    73
  • SpringBoot项目添加mybatis插件

    SpringBoot项目添加mybatis插件SpringBoot项目添加mybatis插件项目场景:    对SpringBoot项目,如何在Mybatis中添加插件可以直接从dao->xml层业务实现:    下载插件MybatisX    File->Settings->plugins安装即可(随后重启IDEA)问题描述:   &nbs

    2022年10月7日
    2
  • bm3d matlab,Note — BM3D「建议收藏」

    bm3d matlab,Note — BM3D「建议收藏」一、引言二、理论三、算法一、引言前面一篇说到Non-localmethod[1],可以归类到spatialmethod中,另外用的比较多的还有transformmethod,基于transformmethod的方法在imagedenoise中也取得了很好的效果,不过理论阐述会比较繁琐,如BLS-GSM-Wavelet。NLM去噪算法使用的是inter-patchcorrelation,而Wavel…

    2022年6月6日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号