【条形码识别】基于matlab条形码识别【含Matlab源码 403期】

举报
海神之光 发表于 2022/05/29 03:16:36 2022/05/29
【摘要】 一、获取代码方式 获取代码方式1: 完整代码已上传我的资源: 【条形码识别】基于matlab条形码识别【含Matlab源码 403期】 获取代码方式2: 通过订阅紫极神光博客付费专栏,凭支付凭证,私信...

一、获取代码方式

获取代码方式1:
完整代码已上传我的资源: 【条形码识别】基于matlab条形码识别【含Matlab源码 403期】

获取代码方式2:
通过订阅紫极神光博客付费专栏,凭支付凭证,私信博主,可获得此代码。

备注:订阅紫极神光博客付费专栏,可免费获得1份代码(有效期为订阅日起,三天内有效);

二、二维条形码识别简介

采用数字图像处理技术对二维条码进行识别, 是二维条形码识别中较常用的方法, 它在处理污损的条形码方面有光电识别方法无法比拟的优势。另外图像式识别方法对识别角度的要求没有光电识别方法那么严格, 对有些二维条形码 (如QR Code码) 可以以任意的角度识别。

1 图像式条形码识别过程
在图像式条形码识别过程中, 首先使用图像采集设备采集二维条形码图像, 然后利用图像处理技术对条形码图像进行去噪和分割处理, 最后调用条码特征读取算法, 读出条码值并显示识别结果, 图3是图像式条形码识别过程, 其中各模块的功能如下:

(1) 图像采集。通过数码相机、扫描仪或专用的图像传感器, 如CCD图像传感器或CMOS图像传感器等设备采集条形码图像。

(2) 图像预处理。图像预处理过程主要包括图像降噪、背景分离、图像校正等环节。由于采集系统或其他原因产生的噪声, 采集的图像有些比较模糊或存在黑白孤立点, 这对条码图像的进一步处理极为不利, 因此要根据条码图像噪声是否严重, 选择一种或多种滤波器进行滤波, 去除噪声。目前采用较多的是中值滤波法。背景分离是将条码区与背景分离, 从而避免在没有有效信息的区域进行特征提取, 提高后续处理的速度。背景分离一般采用标准差阈值跟踪法, 图像条码部分由黑白相间的条块组成, 灰度变化大, 因而标准差较大;而背景部分灰度分布较为平坦, 标准差较小。将条码图像分块, 每个小块的标准差若大于某一阈值, 则该小块中的所有像素点为有效;否则为背景。由于采集进来的图像总会出现一定的倾斜和偏移产生几何畸变, 给快速、正确地识别条码带来困难, 因此必须进行图像校正, 一般方法是:利用行差运算与Hough变换相结合, 快速、准确找到条码图像边界线, 计算出倾斜角度, 通过双线性插值对条码图像进行校正。
在这里插入图片描述
图1 图像式条形码识别过程
(3) 二值化处理。条码识别是以二值图像为基础的, 图像二值化算法很多, 条码图像直方图具有很好的双峰特性, 一般采用大津阈值法[4]就能够对于条码图像进行很好地分割。图像二值化之后, 二值图像中“1”像素代表黑条部分, “0”像素代表白条部分。

(4) 边缘检测。条码识别问题的实质是边缘检测的问题, 传统的条码识别算法是根据二阶导数零交叉来检测条码边缘[2,6]。

(5) 条码读取。根据确定的条码边缘确定条码黑白模块宽度, 利用不同的条码编码规则编制相应的译码程序, 确定条码字符值, 这一算法是非常成熟的。

(6) 结果显示和处理。一般由计算机显示条码识别的结果, 并可根据结果进行实际应用中的处理。

2 图像式条码识别技术难点
在图像式的条形码识别过程中, 若能知道条码条空宽度值, 对于不同的条码都有很成熟的算法来确定条码符号值。因此在图像式条码识别过程中, 图像处理部分的算法是十分重要的, 不同的图像处理方法将影响后续的条码识别结果。图像处理过程中的技术难点如下:

(1) 图像模糊问题。因条码印刷质量差、光照较弱、摄像设备质量等原因, 采集的条形码图像比较模糊, 黑白条块之间的边缘不清晰, 甚至黑白条的边缘几乎融合在一起。针对这一问题, 目前国内的一些处理方法都采用各种经典滤波技术对条码图像进行去噪, 如广泛采用的中值滤波技术。当采集图像非常模糊时, 这种处理方法具有一定局限性, 有时甚至导致条码无法识别。

(2) 边缘检测问题。在传统算法中一般是根据二阶导数零交叉来检测条码边缘。由于图像采集、图像滤波过程中在条码图像边缘处会有一定程度的模糊。又由于在条码图像去噪时, 大都选用经典的中值滤波算法, 该算法对椒盐噪声去噪声效果很明显, 但对高斯噪声去噪效果却较差。而在实际应用中, 图像采集产生的模糊基本上都是高斯噪声, 而中值滤波法对该噪声不能有效地去除。在边缘模糊情况下采用二阶导数零交叉来检测条码边缘会有1~2个像素的偏差, 这对条码的条空宽度的确定会产生影响, 从而影响识别。因此边缘模糊是影响条码识别的重要因素。

3 解决技术难点的方法
要解决边缘模糊问题, 必须对噪声进行分析。我们知道平滑的图像主要集中于中低频部分, 噪声信息或边缘信息主要集中在高频段。通常的滤波方法都是不加区分的滤掉高频信息, 不可避免地也会滤掉边缘信息, 从而造成图像边缘模糊。文献[6]提出了一种基于边缘检测的小波去噪方法, 该方法利用小波变换良好的时频特性, 只要沿着梯度方向检测小波变换系数模值的局部极大值点, 即可得到图像的边缘点, 但小波系数的模值极大值点也可能对应着噪声点。因此在检测出小波系数的极大值后, 还要去除与噪声点对应的小波系数。噪声的Lipschitz指数为负, 信号的Lipschitz指数为正, 它们随着尺度的增大信号系数逐渐变大, 而噪声系数逐渐变小。根据这一特点可除去噪声造成的虚假边缘, 将非噪声点的模值极大点连接起来得到图像的边缘。这种方法既可达到去噪目的又可保持图像的边缘, 这种把去噪和边缘检测结合起来的新思路在一定程度上解决了去噪引起图像边缘模糊的难题。

二、部分源代码

clc;
close all;
%启动定时器,测试软件性能
[filename,filepath]=uigetfile('*.jpg','打开文件');%gui中打开文件
filep=strcat(filepath,filename);
%filep
Image=imread(filep);
tic;
%读取图像并二值化
% Image = imread('0081.jpg');
level = graythresh(Image);  %获取图像二值化的阈值
bw = im2bw(Image,level);    %二值化处理
imshow(bw);
t = 1;
p = 1;
[m n] = size(bw);
%初步计数黑白条的书目
q = round(m/2);
    for i=q
        for j=1:n-1
            if bw(i,j)==0&&bw(i,j+1)==1%颜色变化由黑色变成白色,黑条
                x(t) = j;
                 t = t+1;
            end
       
        end
    end


for i=q
    for j=1:n-1
        if bw(i,j)==1&&bw(i,j+1)==0 %颜色变化由白色变成黑色,白条
            y(p) = j;
             p = p+1;
        end
       
    end
end
pin = 0;
 while length(x)~=30||length(y)~=30
     %%等待提示信息
        if pin ==0
        display('正在扫码,请对准而条形码............');
        end
        pin = pin+1;
     %条形码有损坏是逐行扫描
       for pp=q:round(5*m/6)
           t=1;
           p=1;
            if length(x)==30&&length(y)==30 %通过判断黑白条数测试当前行有无算坏
                break;
            end
                for i=pp
                    for j=1:n-1
                        if bw(i,j)==0&&bw(i,j+1)==1
                            x(t) = j;
                            t = t+1;
                        end
                    end
                end
                for i=pp
                    for j=1:n-1
                        if bw(i,j)==1&&bw(i,j+1)==0
                            y(p) = j;
                            p = p+1;
                        end
       
                    end
                end
       end
 end 
 if length(x)~=30||length(y)~=30
     display('扫码错误!');
     return;
 end
 if i~=round(m/2)
     display('该条形码已受损,但仍然可以正常扫描');
 end
%计算每个条—空的宽度,利用所记录在xy数组中的坐标值,对应相减
 for ii=1:30
    if ii==1
        d(ii)=x(ii)-y(ii);      %计算第一个条的宽度
        d(ii+1)=y(ii+1)-x(ii);  %计算第一个空的宽度
    end
     if ii>1
         if ii>1&&ii<30
        d(2*ii) = y(ii+1)-x(ii); %分别计算第2~29个空的宽度
        d(2*ii-1)=x(ii)-y(ii);   %分别计算第2~29个条的宽度
     elseif ii==30
         d(ii*2-1)=x(ii)-y(ii);   %总共有59个条-空,单独计算第三十个条的宽度
         end
     end    
end


j  = 3;
for i=1:6               
    r(i)=(d(j+1)+d(j+2)+d(j+3)+d(j+4))/7;       %计算左边六个字的基准码的宽度
end
j=32;
for i=7:12
    r(i)=(d(j+1)+d(j+2)+d(j+3)+d(j+4))/7;       %计算右边五个字的基准码的宽度
end
n=0;%四字计数
i=1;
j1=1;
j=4;%跳过起始符,从左边第一个开始读码
flag0=0;%作为标识符,将样条交替翻译成1或者0
while j<=56
    if n==4
        n=0;
        i=i+1;
    end
    if d(j)<0.5*r(i)%小于0.5舍去
        return;
    elseif d(j)<1.5*r(i)&&d(j)>0.5*r(i)%0.5~1.5记为1个值
        if flag0==0
            bs(j1)={'0'};%对于的被译码
        else
             bs(j1)={'1'};   
        end
       j1=j1+1;
    elseif (d(j)>=1.5*r(i))&&(d(j)<2.5*r(i))%1.5~2.5记为2个值
        if flag0==0
            bs(j1)={'00'};
        else
            bs(j1)={'11'};
        end
       j1=j1+1;
    elseif (d(j)>=2.5*r(i))&&(d(j)<3.5*r(i))%2.5~3.5记为3个值
       if flag0==0
           bs(j1)={'000'};
       else
           bs(j1)={'111'};
       end
       j1=j1+1;
    elseif (d(j)>=3.5*r(i))&&(d(j)<4.5*r(i))%3.5~4.5记为4个值
       if flag0==0
           bs(j1)={'0000'};
       else
           bs(j1)={'1111'};
       end
       j1=j1+1;
    else
        return;
    end
    
    n=n+1;
    
    if flag0==0
        flag0=1;
    else
        flag0=0;
    end

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154

四、运行结果

在这里插入图片描述

五、matlab版本及参考文献

1 matlab版本
2014a

2 参考文献
[1] 蔡利梅.MATLAB图像处理——理论、算法与实例分析[M].清华大学出版社,2020.
[2]杨丹,赵海滨,龙哲.MATLAB图像处理实例详解[M].清华大学出版社,2013.
[3]周品.MATLAB图像处理与图形用户界面设计[M].清华大学出版社,2013.
[4]刘成龙.精通MATLAB图像处理[M].清华大学出版社,2015.
[5]赵群礼,周秋平.基于图像的二维条形码识别技术研究[J].合肥师范学院学报. 2010,28(06)

文章来源: qq912100926.blog.csdn.net,作者:海神之光,版权归原作者所有,如需转载,请联系作者。

原文链接:qq912100926.blog.csdn.net/article/details/114127313

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。