资讯详情

【条形码识别】基于matlab条形码识别系统【含Matlab源码 096期】

一、获取代码的方式

我的资源已上传到完整代码: 基于条形码识别matlab条含条形码识别系统Matlab源码 096期】 (https://download.csdn.net/download/TIQCmatlab/62925370) 点击上面蓝色字体,直接付费下载,即可。

付费专栏图像处理(Matlab)

点击蓝色字体付费栏图像处理(Matlab),扫描上面的二维码,付费299.9元订阅海神光博客,私信博主凭支付凭证可免费获得上传本博客CSDN资源代码(订阅日起三天内有效); 点击CSDN资源下载链接:上传本博客CSDN资源代码

二、二维条码识别简介

二维条码采用数字图像处理技术识别, 是二维条码识别中常用的方法, 它具有光电识别方法方面具有无与伦比的优势。此外,图像识别方法对识别角度的要求不如光电识别方法严格, 一些二维条形码 (如QR Code码) 可以从任何角度识别。

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

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

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

(4) 边缘检测。条码识别的本质是边缘检测, 传统的条导数零交叉,传统的条码识别算法是检测条码边缘[2,6]。

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

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

在图像条形码识别过程中, 若能知道条码条的空宽值, 条码符号值由不同条码的算法决定。因此,在图像条码识别过程中, 图像处理部分的算法非常重要, 不同的图像处理方法将影响后续的条码识别结果。图像处理过程中的技术难点如下:

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

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

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

三、部分源代码

clc;clear;close all; ImageSrc=BinaryImage(imread('..\Pic\3.bmp')); ImageSrc=BinaryImage(imread('..\Pic\Demo12.bmp')); ImageSrc=BinaryImage(imread('..\Pic\Demo1211.bmp')); ImageSrc=BinaryImage(imread('..\Pic\李梦1.bmp'));
ImageSrc=BinaryImage(imread('..\Pic\未1命名.bmp'));
ImageSrc=BinaryImage(imread('..\Pic\新978.bmp'));
 
[ImageHeight,ImageWidth]=size(ImageSrc);
ImageArray=ones(size(ImageSrc));
ImageArray(find(ImageSrc>=160))=0;
subplot(211);imshow(flipud(ImageSrc));
subplot(212);imshow(flipud(ImageArray),[]);
arPixelH=sum(ImageArray,1);
arPixelV=sum(ImageArray,2);%左右方向投影
 
tempMax = max(arPixelV);
arMark=zeros(size(ImageArray,1));
 
arDifference=arPixelV(2:end)-arPixelV(1:end-1);
 
% 如果该行像素足够多且变化不大,标记为true
% 相当于与的关系abs(arDifference)<20 && (arPixelV[i]>(0.75*tempMax)
arMark(find(abs(arDifference)<20))=1;
arMark(find(arPixelV<=0.75*tempMax))=0;
 
% 确定包含条码的行
iLengthThrehold=40;
for i=1:ImageHeight-iLengthThrehold+1
    iCount=length(find (arMark(i:i+iLengthThrehold-1)==1 )   );
    if(iCount >= 37)	
		ImageTop = i+10;	%确定顶部
        break;
    end
end
 
for i=ImageHeight:-1:iLengthThrehold
    iCount=length(find (arMark(i:-1:i-iLengthThrehold+1)==1 )   );
    if(iCount >= 37)	
        ImageBottom = i-10;	%确定顶部
        break;
    end
end
 
arLeftEdge=zeros(ImageHeight,1);
arLeftEdge1=arLeftEdge;
arDelta=arLeftEdge;
 
% 寻找左边缘,为了保证鲁棒性,在已经确定的上下边界内全局搜索
for i=ImageTop:ImageBottom
    for j=21:ImageWidth
        if( (ImageArray(i,j-1)==0) && (ImageArray(i,j)==1) )		
            arLeftEdge(i) = j;
				break;
        end
    end
end
[tempMax,iMax]=max(arLeftEdge);
 
% 倾斜度不能大于1/10
iCount = 0;
for i=ImageTop:ImageBottom
    if( abs(tempMax-arLeftEdge(i)) < abs(i-iMax)/6+1 )
		iCount=iCount+1;
    end
end
if( (iCount/(ImageBottom-ImageTop))<0.6 )
		display('failure1!');
        return;
end
 
for n=0:28
    for i=ImageTop:ImageBottom
        for j=arLeftEdge(i)+1:ImageWidth
            if( (ImageArray(i,j-1)==1) && (ImageArray(i,j)==0) )			
                arLeftEdge1(i) = j;		break;
            end
        end
        arDelta(i) = arLeftEdge1(i) - arLeftEdge(i);
    end    
    tempArray=arDelta;
    
    %排序
    for i=ImageTop:ImageBottom-1
        for j=ImageBottom:-1:i+1
            if(tempArray(j)< tempArray(j-1))
                tempSwap = tempArray(j);
                tempArray(j)= tempArray(j-1);
                tempArray(j-1) = tempSwap;
            end
        end
    end
    t0=floor(ImageTop+(ImageBottom-ImageTop)/2);
    t1=t0+2;
    t2=t0-2;
    if(tempArray(t1)-tempArray(t2)>1) display('failure1!');  return;
    else			arWidth(2*n+1) = tempArray(t0);
    end
    
    %调整下一列边缘    
    for i=ImageTop:ImageBottom	
        if(abs(arDelta(i) - arWidth(2*n+1))>2)
				arLeftEdge1(i) = arLeftEdge(i) + arWidth(2*n+1);
        end
        arLeftEdge(i)= arLeftEdge1(i);
    end
    
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % 搜索空的右边缘
    for i=ImageTop:ImageBottom
        for j = arLeftEdge(i)+1:ImageWidth
            if  (ImageArray(i,j-1)==0) && (ImageArray(i,j)==1) 
                arLeftEdge1(i) = j;
                break;
            end
        end
        arDelta(i) = arLeftEdge1(i) - arLeftEdge(i);
    end
    tempArray = arDelta;
    for i=ImageTop:ImageBottom-1
        for j=ImageBottom:-1:i+1
            if(tempArray(j)< tempArray(j-1))
                tempSwap = tempArray(j);
                tempArray(j)= tempArray(j-1);
                tempArray(j-1) = tempSwap;
            end
        end
    end
    t0=floor(ImageTop+(ImageBottom-ImageTop)/2);
    t1=t0+2;
    t2=t0-2;
    if(tempArray(t1)-tempArray(t2)>1) display('failure1!');  return;
    else			arWidth(2*n+2) = tempArray(t0);
    end
    
    %调整下一列边缘
    for i=ImageTop:ImageBottom	
        if(abs(arDelta(i) - arWidth(2*n+2))>2)
				arLeftEdge1(i) = arLeftEdge(i) + arWidth(2*n+2);
        end
        arLeftEdge(i)= arLeftEdge1(i);
    end;
    
end
 
%%  搜索最后一个条的右边缘
for i=ImageTop:ImageBottom
    for j = arLeftEdge(i)+1:ImageWidth
        if  (ImageArray(i,j-1)==1) && (ImageArray(i,j)==0) 
            arLeftEdge1(i) = j;
            break;
        end
    end
    arDelta(i) = arLeftEdge1(i) - arLeftEdge(i);
end
tempArray=arDelta;    
%排序
for i=ImageTop:ImageBottom-1
    for j=ImageBottom:-1:i+1
        if(tempArray(j)< tempArray(j-1))
            tempSwap = tempArray(j);
            tempArray(j)= tempArray(j-1);
            tempArray(j-1) = tempSwap;
        end
    end
end
t0=floor(ImageTop+(ImageBottom-ImageTop)/2);
t1=t0+2;
t2=t0-2;
n=29;
if(tempArray(t1)-tempArray(t2)>1) display('failure1!');  return;
else			arWidth(2*n+1) = tempArray(t0);
end
 
% %调整下一列边缘    此段程序不需要
% for i=ImageTop:ImageBottom	
%     if(abs(arDelta(i) - arWidth(2*n+1))>2)
%             arLeftEdge1(i) = arLeftEdge(i) + arWidth(2*n+1);
%     end
%     arLeftEdge(i)= arLeftEdge1(i);
% end
barnumber=[9,BarRecognize(arWidth)];
if( checkcode(barnumber)==1)
    display(['二维码识别结果:',num2str(barnumber)]);
else display('识别错误!');
end
 
 

四、运行结果

五、matlab版本及参考文献

2014a

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

标签: 传感器条码

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台