%%读取符号字符集
load symcodes.mat -ascii
%%读取图像
src = imread('2.bmp');
%%取图像的R分量
src = src(:,:,1);
%figure,imshow(src)
%%二值化
src = (src > 160) * 255;
[row,col]=size(src)
%figure,imshow(src);
%%旋转
%寻找左侧边线
leftline=zeros(row,2);
k=1;
for i=int16(row/3):row
for j=1:col
if src(i,j) <= 50
if k == 1
leftline(k,1) = i;
leftline(k,2) = j;
k = k+1;
else
if abs(j-leftline(k-1, 2)) < 10
leftline(k,1) = i;
leftline(k,2) = j;
k = k+1;
end
end
break
end
end
end
%描左侧线
%ltl=leftline';
%plot(ltl(2,1:k));
%计算tan值数组
n = int16(k/2);
tanarray=zeros(n,1);
for i=1:n
tanarray(i) = (leftline(i+n, 2)-leftline(i, 2))/(leftline(i+n, 1)-leftline(i, 1));
end
tanarray=sort(tanarray);
%自带函数旋转图像
% ang=atan(0-tanarray(int16(n/2)))*180/pi
% ost=imrotate(src, ang, 'nearest', 'crop');
%figure,imshow(ost);
%手动旋转
% ang=atan(0-tanarray(int16(n/2)))
% sinang = sin(ang);
% cosang = cos(ang);
% new_row = round(col*sinang + row*cosang)
% new_col = round(col*cosang + row*sinang)
% ost = ones(new_row, new_col)*255;
% for i=1:row
% for j=1:col
% xx = round(abs((i-row/2)*cosang-(j-col/2)*sinang+new_row/2));
% yy = round(abs((i-row/2)*sinang+(j-col/2)*cosang+new_col/2));
% ost(xx,yy)=src(i,j);
% end
% end
% figure,imshow(ost);
ang=atan(tanarray(int16(n/2)))*180/pi
ost=imagerotate(src,ang,0);
ost=double(ost);
[new_row,new_col]=size(ost);
%旋转后横向插值
for i=1:new_row
for j=1:new_col-2
if ((ost(i,j)==0)&&(ost(i,j+2)==0)&&(ost(i,j+1)==255))
ost(i,j+1)=0;
end
if ((ost(i,j)==255)&&(ost(i,j+2)==255)&&(ost(i,j+1)==0))
ost(i,j+1)=255;
end
end
end
%旋转后纵插值
for i=1:new_col
for j=1:new_row-2
if ((ost(j,i)==0)&&(ost(j+2,i)==0)&&(ost(j+1,i)==255))
ost(j+1,i)=0;
end
if ((ost(j,i)==255)&&(ost(j+2,i)==255)&&(ost(j+1,i)==0))
ost(j+1,i)=255;
end
end
end
for i=1:new_col
for j=3:new_row-3
if ((ost(j-2,i)==0)&&(ost(j-1,i)==0)&&(ost(j,i)==255)&&(ost(j+1,i)==255)&&(ost(j+2,i)==0)&&(ost(j+3,i)==0))
ost(j,i)=0;
ost(j+1,i)=0;
end
end
end
%figure,imshow(ost);
%%切割出条码范围
%先找上下边线
hvalues=sum(ost');
%figure,plot(hvalues);
T=new_col*255/1.45
for i=2:new_row-5
if (hvalues(i-1)>T) && (hvalues(i)<T) && (hvalues(i+1)<T) && (hvalues(i+2)<T) && (hvalues(i+3)<T) && (hvalues(i+4)<T) && (hvalues(i+5)<T)
topedge=i;
break;
end
end
for i=topedge:new_row-3
if (hvalues(i-1)<T) && (hvalues(i)<T) && (hvalues(i+1)>T) && (hvalues(i+2)>T) && (hvalues(i+3)>T)
botedge=i;
break;
end
end
topedge
botedge
%由上边线寻找左上角端点
midpit=round((topedge+botedge)/2)
for j=3:new_col-5
if (ost(midpit,j-2)>200) && (ost(midpit,j-1)>200) && (ost(midpit,j)<10) && (ost(midpit,j+1)<10) && (ost(midpit,j+2)<10) && (ost(midpit,j+3)<10) && (ost(midpit,j+4)<10)
x1=topedge;
y1=j;
break;
end
end
%由下边线寻找右下角
for j=new_col-5:-1:y1+1
if (ost(midpit,j+5)>200) && (ost(midpit, j+4)>200) && (ost(midpit, j+3)>200) && (ost(midpit, j+2)>200) && (ost(midpit,j+1)>200) && (ost(midpit,j)<10) && (ost(midpit,j-1)<10)
x2=botedge;
y2=j;
break;
end
end
% %由上边线寻找左上角端点
% for j=2:new_col-5
% if (ost(topedge,j-1)>200) && (ost(topedge,j)<10) && (ost(topedge,j+1)<10) && (ost(topedge,j+2)<10) && (ost(topedge,j+3)<10) && (ost(topedge,j+4)<10) && (ost(topedge+2,j+2)<10) && (ost(topedge+3,j+3)<10)
% x1=topedge;
% y1=j;
% break;
% end
% end
% %由下边线寻找右下角
% for j=y1+1:new_col-5
% if (ost(botedge-1,j-1)<10) && (ost(botedge-1,j)<10) && (ost(botedge,j+1)>200) && (ost(botedge,j+2)>200) && (ost(botedge,j+3)>200) && (ost(botedge,j+4)>200) && (ost(botedge+2,j+2)>200) && (ost(botedge+3,j+3)>200)
% x2=botedge;
% y2=j;
% end
% end
%分离条码图像
ost = ost(x1:x2,y1:y2);
[row,col]=size(ost);
figure,imshow(ost)
%%边缘检测
src = ost;
%边缘检测算子
topso=[1 1 1;0 0 0;-1 -1 -1];
botso=[-1 -1 -1;0 0 0;1 1 1];
lefso=[1 0 -1;1 0 -1;1 0 -1];
rigso=[-1 0 1;-1 0 1;-1 0 1];
for i=2:row-1
for j=2:col-1
temp=src(i-1:i+1,j-1:j+1);
tbs =abs(sum(sum(topso.*temp)));
lrs =abs(sum(sum(lefso.*temp)));
if (tbs==0) && (lrs==0)
ost(i,j)=255;
end
end
end
%figure,imshow(ost);
%%消除垂直边缘
src = ost;
dst = ost;
for j=1:col
for i=1:row-1
if src(i+1,j)==src(i,j)
dst(i,j)=255;
end
end
end
%figure,imshow(dst);
%%判断数据码字行数
[row,col]=size(ost);
obs = (dst==0);
rows= sum(obs,2);
%figure,plot(rows);
rowtvalue=round(col/20);
line=zeros(1,row);
k=0;
for i=4:row-3
if (rows(i)>rows(i-1)) && (rows(i)>rows(i-2)) && (rows(i)>rows(i-3)) && (rows(i)>rows(i+1)) && (rows(i)>rows(i+2)) && (rows(i)>rows(i+3)) && (rows(i)>rowtvalue)
k=k+1;
line(k)=i;
end
end
k
line=line(1:k)
%%消除水平边缘
dst = ost;
for i=1:row
for j=2:col
if src(i,j-1)==src(i,j)
dst(i,j)=255;
end
end
end
ost = (dst==255);
figure,imshow(ost);
%%提取码字
linst=zeros(1,k+1);
linst(1)=round(line(1)/2);
for i=1:k-1
linst(i+1)=round((line(i)+line(i+1))/2);
end
linst(k+1)=round((line(k)+row)/2);
%linst
minst=zeros(1,k+1);
codes=zeros(k+1,col);
for i=1:k+1
m=0;
for j=2:col
if ost(linst(i),j)==0
if m==0
m=m+1;
codes(i,m)=j;
temp=j;
else
m=m+1;
codes(i,m)=j-temp;
temp=j;
end
minst(i)=m;
end
end
end
asum=0;
for i=1:k+1
asum=asum+codes(i,1);
end
aunit = round(asum/(k+1)/8)
acodes= zeros(k+1,minst(1));
for i=1:k+1
for j=1:minst(1)
acodes(i,j)=round(codes(i,j)/aunit);
end
end
acodes
%转换符号码字为待解码码字(符号码字 到 数字码字)
[row,col] = size(acodes);
acodes = acodes(:,17:col-17);
[row,col] = size(acodes);
dcodes = zeros(1, round(row*col/8));
k = 0;
for i=1:row
for j=1:8:col
temp = acodes(i,j)*10000000 + acodes(i,j+1)*1000000 + acodes(i,j+2)*100000 + acodes(i,j+3)*10000 + acodes(i,j+4)*1000 + acodes(i,j+5)*100 + acodes(i,j+6)*10 + acodes(i,j+7);
for m=1:3
for n=1:929
if symcodes(m,n)==temp
k=k+1;
dcodes(k)=n-1;
break;
end
end
end
end
end
dcodes
%%解码
%文本模式码表TC,码表里的值是Ascii值,之所以不直接存成字符,是因为有些Ascii值无法显示,比如LF、CR等
%将模式转换符号定义成数值,如下:
%ll=201,锁定为小写字母模式
%ml=202,锁定为混合模式
%pl=203,锁定为标点模式
%al=200,锁定为大写字母模式
%ps=204,转移为标点模式
%as=205,转移为大写字母模式
tc_uc=[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,32,201,202,204];%大写字母模式
tc_lc=[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,32,205,202,204];%小写字母模式
tc_mi=[48,49,50,51,52,53,54,55,56,57,38,13,09,44,58,35,45,46,36,47,43,37,42,61,94,203,32,201,200,204];%混合型模式
tc_do=[59,60,62,64,91,92,93,95,96,126,33,13,09,44,58,10,45,46,36,47,34,124,42,40,41,63,123,125,39,200];%标点型模式
%数字模式码表
nc_tb=[48,49,50,51,52,53,54,55,56,57];
%开始解码,暂时不支持字节型模式,只支持文本模式和数字模式
codelen=dcodes(1);
mode=11;%2->数字型、3->字节型、11->文本模式大写型、12->文本模式小写型、13->文本模式混合
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
用Matlab进行PDF417码图片的预处理和解码,可以纠正任意方向的旋转,压缩包的示例图片都可以正确解码,PDF417码的三种模式只实现了数字模式和文本模式,字节模式和数字模式解码流程一样,就没继续做,因为PDF417码字节模式解码出来的汉字是Unicode格式,还是要转换成GBK18030编码才能在windows系统里显示,所以就没做。
资源推荐
资源详情
资源评论
收起资源包目录
pdf417_decoder_matlab_V0.97.zip (12个子文件)
Matlab
Pdf417Decoder.asv 12KB
imagerotate.m 3KB
4.bmp 350KB
2.jpg 52KB
.picasa.ini 63B
1.bmp 158KB
5.bmp 211KB
symcodes.mat 44KB
Pdf417Decoder.m 12KB
2.bmp 368KB
6.bmp 693KB
3.bmp 405KB
共 12 条
- 1
资源评论
- 天下在我心2017-01-06有借鉴的作用,非常感谢分享!
- zessica2014-10-19希望能标志一下image rotate 的字符集,或者改动一下,我这里显示乱码,有没有高玩能指点一二?
- xdestiny1102015-10-18大部分能够使用,但怎么有些程序会报错?似乎在程序上有些BUG```有没有哪位大神能改改?
- re小零2014-06-01帮同学下的,挺好的,,很有用的啊
- Roshan12342016-01-27不错,很有参考价值
xiaomiaolpj
- 粉丝: 1
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功