QR-Code erzeugen und lesen: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
Zeile 21: Zeile 21:


=== Extrahierung ===
=== Extrahierung ===
=== Bitfield Erzeugung ===
=== Code ===
 
<source lang="matlab">
function [Pair] = extract (Image)
%% extract
% returns extracted QR-Code as bitfield from Image
% (as RGB-Matrix (uint8) width x heigh x RGB )
 
%% Defines
distSizeThresh = 10;
distPosThresh = 100;
distDensityThresh = 15;
diff_Density = 0.04;
 
Padding_Crop = 50;
 
%% Matrix
Pair = [0 0];
DensityPassed = [0 0 0];
 
%% Code
% Image Convertion
gray= rgb2gray(Image);
gray(~(abs(Image(:,:,1)-Image(:,:,2))+abs(Image(:,:,2)-Image(:,:,3))+abs(Image(:,:,1)-Image(:,:,3))<40))=0;
BW=~im2bw(Image,graythresh(Image));
BW(~(abs(Image(:,:,1)-Image(:,:,2))+abs(Image(:,:,2)-Image(:,:,3))+abs(Image(:,:,1)-Image(:,:,3))<40))=0;
cAll = edge(BW,'sobel','vertical')+edge(BW,'sobel','horizontal')+edge(gray,'sobel','horizontal')+edge(gray,'sobel','vertical');
 
%% DISPLAY RESULT
figure
subplot(2,4,1)
imshow(Image)
title('Source')
subplot(2,4,4)
imshow(cAll)
title('Canny')
subplot(2,4,2)
imshow(gray)
title('Grayscale')
subplot(2,4,3)
imshow(~BW)
title('Black/White')
 
%% Find boxes in image
stat = regionprops(logical(bwareaopen(cAll,100)),'boundingbox');
for cnt = 1 : numel(stat)
    if stat(cnt).BoundingBox(3)/stat(cnt).BoundingBox(4)>0.5 && stat(cnt).BoundingBox(3)/stat(cnt).BoundingBox(4)<1.2              %like rectangle will be filtered
        bb(cnt,:) = stat(cnt).BoundingBox;
    else
        bb(cnt,:)=[-1 -1 -1 -1];
    end
   
end
bb(bb(:,:)==-1)=[];
bb=reshape(bb,size(bb,2)/4,4);
 
%% Calculate distance between Size of squares
distSize = sqrt(bsxfun(@minus,bb(:,3),bb(:,3)').^2 + bsxfun(@minus,bb(:,4),bb(:,4)').^2);
distSize(distSize(:,:)>distSizeThresh)=0;
 
%% Calculate distance between position of squares
distPos = sqrt(bsxfun(@minus,bb(:,1),bb(:,1)').^2 + bsxfun(@minus,bb(:,2),bb(:,2)').^2);
distPos(distPos(:,:)>distPosThresh)=0;
 
%% DISPLAY RESULT
subplot(2,4,6)
imshow(cAll)
title('Canny operated / equal square detection')
hold on
 
%% Filter boxes for euqal squares
for k=1:size(distSize,1)
    for l=1:k
        if distSize(k,l)~= 0 && size(find(distSize==distSize(k,l)),1)>=6
            Pair(end+1,:)=[k l];
        end
    end
end
 
 
Pair(1,:)=[];
for k=1:size(Pair,1)
    CropImage1=imcrop(cAll,bb(Pair(k,1),:));
    Density(k,1)=sum(sum(size(find(CropImage1~=0),1)))/(bb(Pair(k,1),3)*bb(Pair(k,1),4));
    CropImage2=imcrop(cAll,bb(Pair(k,2),:));
    Density(k,2)=sum(sum(size(find(CropImage2~=0),1)))/(bb(Pair(k,2),3)*bb(Pair(k,2),4));
    if abs(Density(k,1)-Density(k,2)) < diff_Density
        if Density(k,1)<0.3  && Density(k,1)>0.1
            rectangle('position',bb(Pair(k,1),:),'edgecolor','g','linewidth',2);
            Padding_Crop = max([Padding_Crop bb(Pair(k,1),3:4)./1.1]);
            if size(find(DensityPassed(:,1)==Pair(k,1)),1) == 0
                DensityPassed(end+1,:)=[Pair(k,1) bb(Pair(k,1),1)+0.5*bb(Pair(k,1),3) bb(Pair(k,1),2)+0.5*bb(Pair(k,1),4)];
            end
        end
        if Density(k,2)<0.3  && Density(k,2)>0.1
            rectangle('position',bb(Pair(k,2),:),'edgecolor','g','linewidth',2);
            Padding_Crop = max([Padding_Crop bb(Pair(k,1),3:4)]./1.1);
            if size(find(DensityPassed(:,1)==Pair(k,2)),1) == 0
                DensityPassed(end+1,:)=[Pair(k,2) bb(Pair(k,2),1)+0.5*bb(Pair(k,2),3) bb(Pair(k,2),2)+0.5*bb(Pair(k,2),4)];
            end
        end   
    end
end
if size(DensityPassed,1)>1
    DensityPassed(1,:)=[];
end
 
 
if size(DensityPassed,1)>1
    distDensity = sqrt(bsxfun(@minus,DensityPassed(:,2),DensityPassed(:,2)').^2 + bsxfun(@minus,DensityPassed(:,3),DensityPassed(:,3)').^2);
    for k=1:size(distDensity,1)
        for l=k+1:size(distDensity,2)
            PairDensity(k,1)=k;
            if distDensity(k,l) < distDensityThresh
                if sum(sum(ismember(PairDensity(1:k-1,:),k))) ~= 0
                    PairDensity(k,:)=[];
                    for x=1:size(PairDensity,1)-1
                        if sum(ismember(PairDensity(x,:),k)) ~= 0 && sum(ismember(PairDensity(x,:),l)) == 0
 
                            PairDensity(x,end+1)= l;
                        end
                    end
                else
                    PairDensity(k,end+1)= l;
                end
            end
        end
        if size(PairDensity,1) >= k
            if sum(PairDensity(k,2:end)) == 0
                PairDensity(k,:)=[];
            end
        end
    end
    Passed = [-1 -1];
    for k=1:size(PairDensity,1)
        if sum(PairDensity(k,2:end))>0  % Pair found
            summean = [0 0];
            count = 0;
            for x=1:size(PairDensity,2)
                if PairDensity(k,x) ~= 0
                    summean = [DensityPassed(PairDensity(k,x),2)+summean(1) DensityPassed(PairDensity(k,x),3)+summean(2)];
                    count = count +1;
                end
            end
            Passed(end+1,:)=[summean(1)/count summean(2)/count];
 
        else if PairDensity(k,1) ~= 0  % no Pair
            Passed(end+1,:)= DensityPassed(PairDensity(k,1),2:3);
            end
        end
    end
    subplot(2,4,6)
    plot(Passed(:,1),Passed(:,2),'*r');
    Passed(1,:)=[];
 
    %% Crop Image on Area of Interest
 
    while size(Passed,1)>3
        kick=mean(sqrt(bsxfun(@minus,Passed(:,1),Passed(:,1)').^2 + bsxfun(@minus,Passed(:,2),Passed(:,2)').^2));
        Passed(find(kick==max(kick)),:)=[];
    end
   
    % get dynamic crop area
    Padding_Crop=mean(mean(sqrt(bsxfun(@minus,Passed(:,1),Passed(:,1)').^2 + bsxfun(@minus,Passed(:,2),Passed(:,2)').^2)))/3.5;
    minCrop = [min(Passed(:,1))-Padding_Crop min(Passed(:,2))-Padding_Crop];
    maxCrop = [max(Passed(:,1))+Padding_Crop max(Passed(:,2))+Padding_Crop];
   
    % grop image
    cAllcropped = imcrop(Image, [minCrop maxCrop-minCrop]);
   
    %% DISPLAY RESULT
    subplot(2,4,5)
    imshow(cAllcropped);
    title('croped image from source')
    normCropped = im2bw(cAllcropped);
    subplot(2,4,7)
    imshow(cAllcropped);   
    hold on
    plot(Passed(:,1)-minCrop(1),Passed(:,2)-minCrop(2),'*r'); 
    title('croped image from source with equal squares')
    subplot(2,4,8)
    imshow(normCropped);
    hold on
    plot(Passed(:,1)-minCrop(1),Passed(:,2)-minCrop(2),'*r');
    title('croped image from black/white')
    DensityPassed = [ DensityPassed(:,1) DensityPassed(:,2)-minCrop(1) DensityPassed(:,3)-minCrop(2)];
 
 
    %% Find cornerpairs
    cPair=sqrt(bsxfun(@minus,Passed(:,1),Passed(:,1)').^2 + bsxfun(@minus,Passed(:,2),Passed(:,2)').^2);
    cPair(cPair(:,:)==0)=NaN;
    minPair=min(cPair);
 
else
    fprintf('Less equal Square to find a QR Code!\n');
end
end
</source>


== Siehe auch ==
== Siehe auch ==

Version vom 15. Juni 2014, 15:27 Uhr

Autor: Hauke Ludwig
Betreuer: Prof. Schneider

Wohin man auch blickt ... überall prangert ein QR-Code an Wänden.

Motivation

QR-Codes sind omnipräsent, aber wie codiert man Informationen als QR-Code?

Ziel

Erzeugen Sie ein Matlab Executable, welches aus einer eingegebenen URL einen QR-Code mit beliebigem Logo in der Mitte erzeugt.

Aufgabe

  1. Arbeiten Sie sich in die Erstellung von QR-Codes ein.
  2. Erzeugen Sie ein Matlab Executable, welches aus einer eingegebenen URL einen QR-Code mit beliebigem Logo in der Mitte erzeugt.
  3. Lesen Sie mit Matlab diesen QR-Code ein, so dass dieser Sie auf eine Webpage verlinkt.

Lösung

Vorbearbeitung

Als erser Schritt wird das zu verarbeitende Bild in ein Schwarz/Weiß-Bild konvertiert. Bei dieser Konvertierung werden gleichzeitig alle Bildelemente welche nicht einem Grauwert entsprechen eleminiert. Grauwertentsprechende Werte sind Werte, welche gleichmäßige Anteile an Rot-, Grün- und Blautanteile haben. Das Ergebnis der Eleminierung einzelner Pixel ist deutlich an den schwarzen Flecken im Grayscale-Bild zu erkennen.

Vorbearbeitung des Bildes

Extrahierung

Code

function [Pair] = extract (Image)
%% extract
% returns extracted QR-Code as bitfield from Image 
% (as RGB-Matrix (uint8) width x heigh x RGB )

%% Defines
distSizeThresh = 10;
distPosThresh = 100;
distDensityThresh = 15;
diff_Density = 0.04;

Padding_Crop = 50;

%% Matrix
Pair = [0 0];
DensityPassed = [0 0 0];

%% Code
% Image Convertion
gray= rgb2gray(Image);
gray(~(abs(Image(:,:,1)-Image(:,:,2))+abs(Image(:,:,2)-Image(:,:,3))+abs(Image(:,:,1)-Image(:,:,3))<40))=0;
BW=~im2bw(Image,graythresh(Image));
BW(~(abs(Image(:,:,1)-Image(:,:,2))+abs(Image(:,:,2)-Image(:,:,3))+abs(Image(:,:,1)-Image(:,:,3))<40))=0;
cAll = edge(BW,'sobel','vertical')+edge(BW,'sobel','horizontal')+edge(gray,'sobel','horizontal')+edge(gray,'sobel','vertical');

%% DISPLAY RESULT
figure
subplot(2,4,1)
imshow(Image)
title('Source')
subplot(2,4,4)
imshow(cAll)
title('Canny')
subplot(2,4,2)
imshow(gray)
title('Grayscale')
subplot(2,4,3)
imshow(~BW)
title('Black/White')

%% Find boxes in image
stat = regionprops(logical(bwareaopen(cAll,100)),'boundingbox');
for cnt = 1 : numel(stat)
    if stat(cnt).BoundingBox(3)/stat(cnt).BoundingBox(4)>0.5 && stat(cnt).BoundingBox(3)/stat(cnt).BoundingBox(4)<1.2               %like rectangle will be filtered
        bb(cnt,:) = stat(cnt).BoundingBox;
    else
        bb(cnt,:)=[-1 -1 -1 -1];
    end
    
end
bb(bb(:,:)==-1)=[];
bb=reshape(bb,size(bb,2)/4,4);

%% Calculate distance between Size of squares
distSize = sqrt(bsxfun(@minus,bb(:,3),bb(:,3)').^2 + bsxfun(@minus,bb(:,4),bb(:,4)').^2);
distSize(distSize(:,:)>distSizeThresh)=0;

%% Calculate distance between position of squares
distPos = sqrt(bsxfun(@minus,bb(:,1),bb(:,1)').^2 + bsxfun(@minus,bb(:,2),bb(:,2)').^2);
distPos(distPos(:,:)>distPosThresh)=0;

%% DISPLAY RESULT
subplot(2,4,6)
imshow(cAll)
title('Canny operated / equal square detection')
hold on

%% Filter boxes for euqal squares
for k=1:size(distSize,1)
    for l=1:k
        if distSize(k,l)~= 0 && size(find(distSize==distSize(k,l)),1)>=6
            Pair(end+1,:)=[k l];
        end
    end
end


Pair(1,:)=[];
for k=1:size(Pair,1)
    CropImage1=imcrop(cAll,bb(Pair(k,1),:));
    Density(k,1)=sum(sum(size(find(CropImage1~=0),1)))/(bb(Pair(k,1),3)*bb(Pair(k,1),4));
    CropImage2=imcrop(cAll,bb(Pair(k,2),:));
    Density(k,2)=sum(sum(size(find(CropImage2~=0),1)))/(bb(Pair(k,2),3)*bb(Pair(k,2),4));
    if abs(Density(k,1)-Density(k,2)) < diff_Density
        if Density(k,1)<0.3  && Density(k,1)>0.1 
            rectangle('position',bb(Pair(k,1),:),'edgecolor','g','linewidth',2);
            Padding_Crop = max([Padding_Crop bb(Pair(k,1),3:4)./1.1]);
            if size(find(DensityPassed(:,1)==Pair(k,1)),1) == 0
                DensityPassed(end+1,:)=[Pair(k,1) bb(Pair(k,1),1)+0.5*bb(Pair(k,1),3) bb(Pair(k,1),2)+0.5*bb(Pair(k,1),4)];
            end
        end
        if Density(k,2)<0.3  && Density(k,2)>0.1 
            rectangle('position',bb(Pair(k,2),:),'edgecolor','g','linewidth',2);
            Padding_Crop = max([Padding_Crop bb(Pair(k,1),3:4)]./1.1);
            if size(find(DensityPassed(:,1)==Pair(k,2)),1) == 0
                DensityPassed(end+1,:)=[Pair(k,2) bb(Pair(k,2),1)+0.5*bb(Pair(k,2),3) bb(Pair(k,2),2)+0.5*bb(Pair(k,2),4)];
            end
        end    
    end
end
if size(DensityPassed,1)>1
    DensityPassed(1,:)=[];
end


if size(DensityPassed,1)>1
    distDensity = sqrt(bsxfun(@minus,DensityPassed(:,2),DensityPassed(:,2)').^2 + bsxfun(@minus,DensityPassed(:,3),DensityPassed(:,3)').^2);
    for k=1:size(distDensity,1)
        for l=k+1:size(distDensity,2)
            PairDensity(k,1)=k;
            if distDensity(k,l) < distDensityThresh
                if sum(sum(ismember(PairDensity(1:k-1,:),k))) ~= 0
                    PairDensity(k,:)=[];
                    for x=1:size(PairDensity,1)-1
                        if sum(ismember(PairDensity(x,:),k)) ~= 0 && sum(ismember(PairDensity(x,:),l)) == 0

                            PairDensity(x,end+1)= l;
                        end
                    end
                else
                    PairDensity(k,end+1)= l;
                end
            end
        end
        if size(PairDensity,1) >= k
            if sum(PairDensity(k,2:end)) == 0
                PairDensity(k,:)=[];
            end
        end
    end
    Passed = [-1 -1];
    for k=1:size(PairDensity,1)
        if sum(PairDensity(k,2:end))>0  % Pair found 
            summean = [0 0];
            count = 0;
            for x=1:size(PairDensity,2)
                if PairDensity(k,x) ~= 0
                    summean = [DensityPassed(PairDensity(k,x),2)+summean(1) DensityPassed(PairDensity(k,x),3)+summean(2)];
                    count = count +1;
                end
            end
            Passed(end+1,:)=[summean(1)/count summean(2)/count];

        else if PairDensity(k,1) ~= 0   % no Pair
            Passed(end+1,:)= DensityPassed(PairDensity(k,1),2:3);
            end
        end
    end
    subplot(2,4,6)
    plot(Passed(:,1),Passed(:,2),'*r');
    Passed(1,:)=[];

    %% Crop Image on Area of Interest

    while size(Passed,1)>3
        kick=mean(sqrt(bsxfun(@minus,Passed(:,1),Passed(:,1)').^2 + bsxfun(@minus,Passed(:,2),Passed(:,2)').^2));
        Passed(find(kick==max(kick)),:)=[]; 
    end
    
    % get dynamic crop area
    Padding_Crop=mean(mean(sqrt(bsxfun(@minus,Passed(:,1),Passed(:,1)').^2 + bsxfun(@minus,Passed(:,2),Passed(:,2)').^2)))/3.5;
    minCrop = [min(Passed(:,1))-Padding_Crop min(Passed(:,2))-Padding_Crop];
    maxCrop = [max(Passed(:,1))+Padding_Crop max(Passed(:,2))+Padding_Crop];
    
    % grop image
    cAllcropped = imcrop(Image, [minCrop maxCrop-minCrop]);
    
    %% DISPLAY RESULT
    subplot(2,4,5)
    imshow(cAllcropped);
    title('croped image from source')
    normCropped = im2bw(cAllcropped);
    subplot(2,4,7)
    imshow(cAllcropped);    
    hold on
    plot(Passed(:,1)-minCrop(1),Passed(:,2)-minCrop(2),'*r');   
    title('croped image from source with equal squares')
    subplot(2,4,8)
    imshow(normCropped);
    hold on
    plot(Passed(:,1)-minCrop(1),Passed(:,2)-minCrop(2),'*r');
    title('croped image from black/white')
    DensityPassed = [ DensityPassed(:,1) DensityPassed(:,2)-minCrop(1) DensityPassed(:,3)-minCrop(2)];


    %% Find cornerpairs
    cPair=sqrt(bsxfun(@minus,Passed(:,1),Passed(:,1)').^2 + bsxfun(@minus,Passed(:,2),Passed(:,2)').^2);
    cPair(cPair(:,:)==0)=NaN;
    minPair=min(cPair);

else
    fprintf('Less equal Square to find a QR Code!\n');
end
end

Siehe auch

Beispiele für QR Codes

Weblinks


→ zurück zum Hauptartikel: Digitale Signal- und Bildverarbeitung SoSe2014