Code covered by the BSD License  

Highlights from
Aztec barcode reader

image thumbnail

Aztec barcode reader

by

 

This program can read Aztec barcode from video or pictures. It is partial in Dutch

Uitlezen_frame.m
clc
close all
clear all
%deze barcode reader is geschikt voor zowel de grote als de kleine versie
%van aztec code. Gemaakt voor Project F 2009 door C. ten Hove. Voor vragen
%c.h.tenhove@student.utwente.nl

%detail instellingen 
%D = imread('barcode_opstelling.gif'); hoekmax=1; %laden van een afbeelding
%D = imread('grote.gif'); hoekmax=1; %laden van een afbeelding
%D = imread('barcode.gif'); hoekmax=1; %laden van een afbeelding

D = ladenframe(41,'Video31.mpg'); hoekmax=5;
image(D)

% hoekmax= maximale verwachte verdraaiing van de afbeelding
% detail= hoeveel contrast nodig is om een lijn op te merken
% afstand= minimale geschatte afstand tussen de lijnen.
% detail2= de dichtheid waarmee gescand wordt

afmetingenO=size(D);
z=size(afmetingenO);

if z(2)==3
    B=mean(D,3);
else
    B=D;
end

%sum(sum(abs(fft2(B))))
%Roteren van het plaatje

BW = edge(B,'log');
t =[(-hoekmax):hoekmax (90-hoekmax):(90+hoekmax)];
R= radon(BW,t);
[R locatie]=sort(R,'descend');
[a hoek1]=max(sum(R(1:15,1:(hoekmax*2+2))));
[a hoek90]=max(sum(R(1:15,(hoekmax*2+2):end)));
hoek=floor((t(hoek1)+t(hoek90+hoekmax*2+1)-90)/2);
B=imrotate(B,-hoek);

afmetingenB=size(B);
x=afmetingenB(2);
y=afmetingenB(1);


%schitteringen eruit halen en randen van rotatie wegwerken
gem=mean(mean(B));
if hoek==0 && z(2)==2
else
    for a=1:y
        for b=1:x
            if ((B(a,b)==0) || (B(a,b)>1.6*gem))
                B(a,b)=gem;
            end
        end
    end
end

%Met bovenstaande gegevens kijken wat betere instellingen zijn
afstanden1=sort(locatie(1:30,hoek1)); 
afstanden2=sort(locatie(1:30,hoek90+hoekmax*2+1));
verschil=[];
for a=1:29
    verschil1= afstanden1(a+1,1)-afstanden1(a,1);
    verschil2= afstanden2(a+1,1)-afstanden2(a,1);
    if verschil1>1
        verschil=[verschil verschil1];
    end
    if verschil2>1
        verschil=[verschil verschil2];
    end
end
afstand=floor(median(verschil)/2)+1;
detail2=floor(afstand/3)+1;
detail=floor(y/15)+1;


%afbeelding bijsnijden als er te weinig verandering op een lijn is

if z(2)==3
    [snijden H1 V1]=bijsnijden(B,x,y,afstand);
    B=B(snijden(1):snijden(2),snijden(3):snijden(4));
end

%omzetten in zwart/wit afbeelding
% A = im2bw(B);
% A=single(A);

afmetingenB=size(B);
yb=afmetingenB(1);
xb=afmetingenB(2);

for a=1:yb
    for b=1:xb
        if B(a,b)<=gem
            A(a,b)=0;
        else
            A(a,b)=1;
        end
    end
end



%afmetingen van A bepalen
afmetingen2=size(A);
y2=afmetingen2(1);
x2=afmetingen2(2);

%lijnen scannen om het raster te bepalen----------------
[horizontaal verticaal]=raster(A,x2,y2,afstand,detail,detail2);


%filteren lijnen

h=size(horizontaal);
v=size(verticaal);
a=1;
horizontaal1=[];
verticaal1=[];
vorige=0; %deze is 1 als er de vorige keer een gemiddelde is genomen en loopt op naarmate er meer vorige keren waren

while a<=(h(2)-1)
    if horizontaal(a+1)-horizontaal(a)<afstand
        vorige=vorige+1;
    else
        if vorige==0
          horizontaal1=[horizontaal1 horizontaal(a)];
        else
          horizontaal1=[horizontaal1 floor(mean(horizontaal((a-vorige):(a))))];
          vorige=0;
        end
    end
    a=a+1;
end
if vorige>0
    horizontaal1=[horizontaal1 floor(mean(horizontaal((a-vorige):(a))))];
else
    horizontaal1=[horizontaal1 horizontaal(a)];
end

a=1;
vorige=0;
while a<=(v(2)-1)
    if verticaal(a+1)-verticaal(a)<afstand
        vorige=vorige+1;
    else
        if vorige==0
          verticaal1=[verticaal1 verticaal(a)];
        else
          verticaal1=[verticaal1 floor(mean(verticaal((a-vorige):(a))))];
          vorige=0;
        end
    end
    a=a+1;
end
if vorige>0
    verticaal1=[verticaal1 floor(mean(verticaal((a-vorige):(a))))];
else
    verticaal1=[verticaal1 verticaal(a)];
end

verticaal=verticaal1;
horizontaal=horizontaal1;
h=size(horizontaal);
v=size(verticaal);
%scannen binaire data-------------------------------------

%afstand bepalen en nog rijen toevoegen als er nog wat ontbreekt

verschilv=[];
for a=1:(v(2)-1)
    verschilv=[verschilv verticaal(a+1)-verticaal(a)];
end
if isempty(verschilv)
    verschilv=afstand;
end
verschilvO=floor(median(verschilv));
verschilv=floor(verschilvO/2);

verschilh=[];
for a=1:(h(2)-1)
    verschilh=[verschilh horizontaal(a+1)-horizontaal(a)];
end
if isempty(verschilh)
    verschilh=afstand;
end
verschilhO=floor(median(verschilh));
verschilh=floor(verschilhO/2);

[verticaal horizontaal]=opschonen_raster(horizontaal, verticaal, verschilhO, verschilvO, y2, x2);

if verticaal(end)>=(y2-verschilv)
    verticaal(end)=[];
end
if horizontaal(end)>=(x2-verschilh)
    horizontaal(end)=[];
end

h=size(horizontaal);
v=size(verticaal);


%binair uitlezen

for a=1:h(2)
    for b=1:v(2)
        binair(b,a)=A(verticaal(b)+verschilv,horizontaal(a)+verschilh);
    end
end

zbinair=size(binair);
if (min(zbinair))<15
    disp('barcode is te klein')
end

%uitlezen data--------------------------------------------

%vinden middelpunt

[middelpunt(1),middelpunt(2),kans_op_correct_middelpunt, type]=middel(binair, zbinair);

%binaire rij systematisch uitlezen via verschillende methodes

if type==2
    [rij, rasterP, gegevens, lagenR]=uitlezenl(binair, zbinair, middelpunt);
elseif type==1
    [rij, rasterP, gegevens, lagenR]=uitlezenk(binair, zbinair, middelpunt);
else
    rij=[];
end

%afmetingen uitlezen en eventueel corrigeren

if type==1
    [fgegevens error]=RSeigen(gegevens,4,3);
    lagen=bin2dec(num2str(fgegevens(1:2)))+1;
    k=bin2dec(num2str(fgegevens(3:8)))+1;
elseif type==2
    [fgegevens error]=RSeigen(gegevens,4,5);
    lagen=bin2dec(num2str(fgegevens(1:5)))+1;
    k=bin2dec(num2str(fgegevens(6:16)))+1;
end

%proberen te corrigeren als de afbeelding er niet volledig opstaat
if lagen>lagenR
    disp('de barcode staat niet volledig op de afbeelding')
    if type==2
        Z=zeros(lagen*4+16,lagen*4+16);
        Z((lagen*2+9-middelpunt(1)):((lagen*2+8-middelpunt(1))+zbinair(1)),(lagen*2+9-middelpunt(2)):((lagen*2+8-middelpunt(2))+zbinair(2)))=binair;
        binair=Z;
        middelpunt=[lagen*2+8 lagen*2+8];
        [rij, rasterP, gegevens, lagenR]=uitlezenl(binair, [lagen*4+16 lagen*4+16], middelpunt);
    elseif type==1
        Z=ones(lagen*4+12,lagen*4+12);
        if (((lagen*2+7-middelpunt(1))>0) && ((lagen*2+7-middelpunt(2))>0))
            Z((lagen*2+7-middelpunt(1)):((lagen*2+6-middelpunt(1))+zbinair(1)),(lagen*2+7-middelpunt(2)):((lagen*2+6-middelpunt(2))+zbinair(2)))=binair;
            binair=Z;
            middelpunt=[lagen*2+6 lagen*2+6];
            [rij, rasterP, gegevens, lagenR]=uitlezenk(binair, [lagen*4+12 lagen*4+12], middelpunt);
        else
            rij=[];
        end
    else
        rij=[];
    end
elseif lagen<lagenR
    disp('de barcode staat niet volledig op de afbeelding')
end

lrij=size(rij);

%enen en nullen omdraaien zodat die kloppen als dit nodig is

for a=1:lrij(2)
    if rij(a)==1
        rij(a)=0;
    else
        rij(a)=1;
    end
end

%rij omdraaien zodat de gewone tekst eerst komt

rij=fliplr(rij);

%Reed-Salomon Error correctie----------------------

%het aantal bits van de RS Error correctie bepalen
if((lagenR >= 0) && (lagenR <= 2)) 
    m = 6;
elseif((lagenR >= 3) && (lagenR <= 8)) 
    m = 8;
elseif((lagenR >= 9) && (lagenR <= 22)) 
    m = 10;
elseif (lagenR >= 23)
    m = 12;
end

%Error correctie op de data toepassen
[rij errorc]=RSeigen(rij,m,k);  %eventueel wordt de k later nog aangepast

%uitlezen rij

rij_ascii=uitlezenrij(rij);

%diverse plots
close
scrsz = get(0,'ScreenSize');
figure('name',rij_ascii,'NumberTitle','off','Position',[150 scrsz(4)/20 scrsz(3)/1.32 scrsz(4)/1.19])
colormap(gray)


subplot(2,2,2)
hold on
image(A.*255)
plot([fliplr(horizontaal') fliplr(horizontaal')],[0 y2],[0 x2],[verticaal' verticaal'])
title('Zwart wit met raster')
axis image
axis ij

subplot(2,2,1)
hold on
image(D)
if z(2)==3
    plot(1:x,(H1*y+y)/2,(V1*x+x)/2,1:y,[snijden(3:4) ;snijden(3:4)],[0 y],[0 x],[snijden(1:2) ;snijden(1:2)])
    title('Origineel met randen opzoeken')
else
    title('Origineel')
end
axis image
axis ([0 x 0 y])
axis ij

subplot(2,2,3)
hold on
image(binair.*255)
plot(middelpunt(2),middelpunt(1),'*')
title(['Kans op correct middelpunt: ', num2str(kans_op_correct_middelpunt), '%'])
axis image
axis ij

subplot(2,2,4)
hold on
image(rasterP.*255)
plot(middelpunt(2),middelpunt(1),'*')
title(['Uitgelezen deel, type= ', num2str(type), '.  Error correctie= ', num2str(errorc)])
axis image
axis ij

tekst=rij_ascii





Contact us