clc;
clear;
close all;
warning off;
addpath(genpath(pwd));
ImageSrc=BinaryImage(imread('新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