条形码识别(4)——校验

标签: 机器视觉 条形码识别 Python


1.目标

EAN13条形码一共有13位,最后1位是校验位,该位是通过前12位按照一定的步骤计算出来的。如果按照一定的步骤处理识别出的前12位数据,如果计算结果和识别出的结果相等,识别正确;如果不相等,则重新识别或纠错再校验或提示识别失败。

2.校验码计算方法

以下图所示的条形码举例说明:

条形码的位数起始位为最右一位,即校验位,检验码计算方法如下:

  • 偶位数数值相加乘3((0+2+0+8+1+9)*3=60
  • 不含校验位的奇位数相加(7+4+7+9+3+6=36
  • 将前两步的结果相加(60+36=96
  • 用10减去上一步结果的个位数数值(10-6=4
  • 上一步结果的个位数即为校验码(4

3.实现

需要注意的是Python中list下标从0开始,且从左边开始,与条形码的起始位相反

def check_bar_code(barCode):evens = barCode[11]+barCode[9]+barCode[7]+barCode[5]+barCode[3]+barCode[1]odds = barCode[10]+barCode[8]+barCode[6]+barCode[4]+barCode[2]+barCode[0]sum = evens * 3 + oddsif barCode[12] == (10 - sum % 10) % 10:return Trueelse:return False

4.总结

  • 截止本篇博文为止,理想状态的条形码检测目标已经实现,主要流程如下:

    • 载入图像
    • 图像预处理(灰度化、滤波,二值化等)
    • 扫描条形码,获得bar和space的宽度
    • 相似边距离译码
    • 校验
    • 输出结果
  • 还有几点不足:
    • 前置符默认为6,原则上应该按照左侧数字字符的奇偶性计算得出
    • 默认扫码方向为从左到右,原则上应该检测两侧数字字符的奇偶性,有奇有偶的那一侧为正向
  • 后续剪裁与处理部分有时间再分享出来,欢迎讨论

5.所有源代码

#创建:2016/01/26
#文件:BarCodeIdentification.py
#作者:moverzp
#功能:识别条形码
import sys
import cv2DECODING_TABLE = {'0001101': 0, '0100111': 0, '1110010': 0,'0011001': 1, '0110011': 1, '1100110': 1,'0010011': 2, '0011011': 2, '1101100': 2,'0111101': 3, '0100001': 3, '1000010': 3,'0100011': 4, '0011101': 4, '1011100': 4,'0110001': 5, '0111001': 5, '1001110': 5,'0101111': 6, '0000101': 6, '1010000': 6,'0111011': 7, '0010001': 7, '1000100': 7,'0110111': 8, '0001001': 8, '1001000': 8,'0001011': 9, '0010111': 9, '1110100': 9,    }EDGE_TABLE = {2:{2:6,3:0,4:4,5:3},3:{2:9,3:'33',4:'34',5:5},4:{2:9,3:'43',4:'44',5:5},5:{2:6,3:0,4:4,5:3},}INDEX_IN_WIDTH = (0, 4, 8, 12, 16, 20, 24, 33, 37, 41, 45, 49, 53)
def get_bar_space_width(img):row = img.shape[0] *1/2currentPix = -1lastPix = -1pos = 0width = []for i in range(img.shape[1]):#遍历一整行currentPix = img[row][i]if currentPix != lastPix:if lastPix == -1:lastPix = currentPixpos = ielse:width.append( i - pos )pos = ilastPix = currentPixreturn widthdef divide(t, l):if float(t) / l < 0.357:return 2elif float(t) / l < 0.500:return 3elif float(t) / l < 0.643:return 4else:return 5def cal_similar_edge(data):similarEdge = []#先判断起始符limit = float(data[1] + data[2] + data[3] ) / 3 * 1.5if data[1] >= limit or data[2] >= limit or data[3] >= limit:return -1#宽度提取失败index = 4while index < 54:#跳过分隔符区间if index==28 or index==29 or index==30 or index==31 or index==32:index +=1continue#字符检测T1 = data[index] + data[index+1]T2 = data[index+1] + data[index+2]L = data[index] + data[index+1] + data[index+2] + data[index+3]similarEdge.append( divide(T1, L) )similarEdge.append( divide(T2, L) )index += 4return similarEdgedef decode_similar_edge(edge):barCode = [6]#第一个字符一定是6,中国区for i in range (0, 24, 2):#每个字符两个相似边,共12个字符barCode.append( EDGE_TABLE[edge[i]][edge[i+1]] )return barCodedef decode_sharp(barCode, barSpaceWidth):for i in range(0, 13):if barCode[i] == '44':index = INDEX_IN_WIDTH[i]c3 = barSpaceWidth[index+2]c4 = barSpaceWidth[index+3]if c3 > c4:barCode[i] = 1else:barCode[i] = 7            elif barCode[i] == '33':index = INDEX_IN_WIDTH[i]c1 = barSpaceWidth[index]c2 = barSpaceWidth[index+1]if c1 > c2:barCode[i] = 2else:barCode[i] = 8elif barCode[i] == '34':index = INDEX_IN_WIDTH[i]c1 = barSpaceWidth[index]c2 = barSpaceWidth[index+1]if c1 > c2:barCode[i] = 7else:barCode[i] = 1            elif barCode[i] == '43':index = INDEX_IN_WIDTH[i]c2 = barSpaceWidth[index+1]c3 = barSpaceWidth[index+2]if c2 > c3:barCode[i] = 2else:barCode[i] = 8def check_bar_code(barCode):evens = barCode[11]+barCode[9]+barCode[7]+barCode[5]+barCode[3]+barCode[1]odds = barCode[10]+barCode[8]+barCode[6]+barCode[4]+barCode[2]+barCode[0]sum = evens * 3 + oddsif barCode[12] == (10 - sum % 10) % 10:return Trueelse:return False
#载入图像
img = cv2.imread('res\google6.jpg')
grayImg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#转换成单通道图像
ret, grayImg = cv2.threshold(grayImg, 200, 255, cv2.THRESH_BINARY)#二值化
grayImg = cv2.medianBlur(grayImg, 3)#中值滤波
#提取条空宽度
barSpaceWidth = get_bar_space_width(grayImg)
print 'bar & space\'s numbers:', len(barSpaceWidth)#只有60是正确的
print barSpaceWidth
#计算相似边数值
similarEdge = cal_similar_edge(barSpaceWidth)
if similarEdge == -1:print 'barSpaceWidth error!'sys.exit()
print 'similarEdge\'s numbers:', len(similarEdge)
print similarEdge
#相似边译码
barCode = decode_similar_edge(similarEdge)
#针对‘#’译码
decode_sharp(barCode, barSpaceWidth)
#校验
valid = check_bar_code(barCode)
valid = 1
print 'barcode:\n', barCode if valid else 'Check barcode error!'height = img.shape[0]
width = img.shape[1]
cv2.line(grayImg, (0, height/2), (width, height/2),(0, 255, 0), 2)#画出扫描的行#显示图像
cv2.imshow("origin", img)
cv2.imshow("result", grayImg)key = cv2.waitKey(0)
if key == 27:cv2.destroyAllWindows()

条形码识别(4)——校验相关推荐

  1. matlab speex的语音处理模块_基于MATLAB的条形码识别系统[GUI,可识别几十个图片]...

    1.1 应用MATLAB识别条形码总体设计 本设计为基于MATLAB的条形码识别系统,带有一个GUI界面. GUI设计界面 1.1.1 程序总体设计思路 在上节中我们简单的介绍了MATLAB的发展以及 ...

  2. 条形码识别(1)——基础知识

    条形码识别(1)--基础知识 标签: 机器视觉 条形码识别 Python 1.序 马上就要放寒假了,老师那边貌似也没有什么任务,这一个礼拜不能闲着,思索着做一点东西练练手,看书和实践结合起来才是最有效 ...

  3. 【百度快照】基于MATLAB GUI的条形码识别系统

    1.1 应用MATLAB识别条形码总体设计*** 本设计为基于MATLAB的条形码识别系统,带有一个GUI界面. 1.1.1 程序总体设计思路 在上节中我们简单的介绍了MATLAB的发展以及优点.在以 ...

  4. 基于MATLAB的条形码识别系统

    1.1 应用MATLAB识别条形码总体设计 本设计为基于MATLAB的条形码识别系统,带有一个GUI界面. 资源链接 https://gitee.com/chending006/tiaoxingmah ...

  5. 嵌入式AI设备--火星人视觉传感器--条形码识别功能

    一维条形码应用广泛,本文选择最具代表性的EAN-13条形码,它采用互相平行.不同宽窄的59个黑白条纹构成,可以解码为数字0-9.条形码的识别功能实现过程如下图所示,一共分为7个过程,分别为:灰度转换. ...

  6. OpenCV条形码识别

    OpenCV条形码识别 条形码识别 目标 基本 EAN 13 条码检测器 初始化 探测 解码 结果 原始图片 detectAndDecode的结果 条形码识别 目标 在这一章当中, 我们将熟悉Open ...

  7. 条形码识别(3)——译码

    条形码识别(3)--译码 标签: 机器视觉 条形码识别 Python 1.目标 本节的主要目标是根据bar和space的宽度译出其所表示的字符. 2.算法 条形码译码常见的方法有2个:平均值译码法和相 ...

  8. 全攻略:实现pynq-z2条形码识别

    文章目录 1.前言 2. linux配置 2.1解决pynq联网 2.2解决pyzbar库下载 2.3解决jupyter导入库 2.3.1 首先说明问题的由来 2.3.2 方法一: 2.3.3 方法二 ...

  9. Python条码识别:使用Python进行条形码识别的详细教程

    Python条码识别:使用Python进行条形码识别的详细教程 身处数字化时代,条形码作为重要的物流标识符,已经广泛应用于各行各业.对于条形码的识别,在Python中,有许多开源库可以使用,例如Zba ...

最新文章

  1. sizebox模型下载_css 盒模型、box-sizing 学习笔记
  2. php 函数中静态变量的问题
  3. 目前用的java几_java目前常用的几种定时任务
  4. POJ 2031 Building a Space Station
  5. Java并发编程-线程池底层工作原理
  6. rtl驱动 ubuntu 禁用_【Ubuntu】UEFI安装Windows 10和Ubuntu 18.04双系统(深度爬坑)
  7. Qgis 3.18 的安装步骤
  8. 银河麒麟支持php吗,银河麒麟操作系统下载
  9. torch中dataloader加速
  10. 基于ZigBee的城市照明监控系统网关节点的软硬件设计
  11. [深度学习论文笔记]3D AGSE-VNet: An Automatic Brain Tumor MRI Data Segmentation Framework
  12. Charles开启代理后手机无法上网
  13. 一文系统搞懂协同推荐算法(二)
  14. 计算机音乐数字谱铃舟,天涯明月刀手游音乐曲谱大全 天涯明月刀曲谱大全简单图片...
  15. QT<八> 绘图事件、绘图设备
  16. Vue 钩子函数activated未触发
  17. 华为交换机S5720S-52P-SI-AC配置web管理端IP地址
  18. 一名合格的网络工程师,我们需要掌握哪些基本知识
  19. Linux菜单栏添加程序启动项
  20. ArangoDB 多模型数据库概念

热门文章

  1. html 小游戏 五子棋
  2. 防火墙测试-思博伦Avalanche 3100_双极未来
  3. 期货做空的作用及期货做空的含义
  4. python输入数字替换为中文_Python把中文数字替换成阿拉伯数字
  5. IM软件应用及市场分析
  6. PaddlePaddle领航团 OpenCV基础知识点总结
  7. 扑克牌游戏html代码,扑克牌代码
  8. 教大家如何确定高低温测试仪器的故障
  9. PHP 简单的小偷程序
  10. IP 分支组网解决方案