%%读取符号字符集
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->文本模式混合
xiaomiaolpj
- 粉丝: 1
- 资源: 6
最新资源
- HTML与CSS制作的静态圣诞树图案教程
- 基于STM32单片机的智能晾衣架高分项目源码(小白也可实战).zip
- STM32+ESP8266 WIFI遥控小车源码
- C# winform新版盒盖机[完整源码解压后1.8G].zip
- Python实现控制台圣诞树图形打印
- node-v20.10.0-x64.msi 下载
- 约瑟夫问题及递推公式的计算机科学应用
- 基于stm32f103c8t6的智能台灯源码
- 本地磁盘学习使用仅供参考
- C# winform-SerialPort串口Demo.zip
- putty远程连接服务器利器,ssh连接工具
- 二维码生成工具,适用于window平台汉字转二维码的工具,文本传输
- openEuler 22.03-SP4 在线部署 Kubernetes
- C# WPF-CCS线体,写的测试MES用的Demo .zip
- 自动蒸馏清洁机sw18可编辑全套技术开发资料100%好用.zip
- C++实现Qt和Mysql的智能停车场管理系统源码+数据库(高分项目)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈