Augmented Reality: Wörterbuch: Unterschied zwischen den Versionen
Zeile 36: | Zeile 36: | ||
Unter der Annahme eines rechteckigen Schildes welches sich gut von der Umgebung abhebt wird kann das Bild auf ein Kantenbild reduziert werden. | Unter der Annahme eines rechteckigen Schildes welches sich gut von der Umgebung abhebt wird kann das Bild auf ein Kantenbild reduziert werden. | ||
Mit Hilfe dieser Reduzierung und der Trennung vom Hintergrund werden die Schild Informationen hervorgehoben. | |||
<source lang="matlab"> | <source lang="matlab"> |
Version vom 20. Juni 2014, 18:29 Uhr
Autor: Christoph Wiegand
Betreuer: Prof. Schneider
Motivation
Word Lens ist ein geniales App, welches Schilder in alle Weltsprachen übersetzt.
Ziel
Programmieren Sie eine Schildererkennung und Übersetzung in Deutsch.
Aufgabe
- Erkennen Sie die Schrift auf den Schildern
- Ersetzen Sie diese Schrift perspektivisch durch eine passende deutsche Beschriftung im Videobild.
- Präsentieren Sie Ihr Ergebnis in der Form des Videos von Word Lense.
Lösung
Diese Lösung übersetzt Wörter in Beispielbildern. Diese Bilder zeigen rechteckige Schilder mit Text.
1.Schritt: Einlesen der Daten
Zuerst müssen alle benötigten Daten eingelesen werden. In dem Skrip "buchstaben_einlesen;" werden die Schwarz/Weiß Tamplates geladen. Die Grundlage für die Übersetzung stellt das Cell Array "vokabeln", da der Schwerpunkt der Aufgabe in der Bildverarbeitung besteht, wird eine Wort für Wort Übersetzung angewendet.
%% Bild und Daten einlesen
buchstaben_einlesen;
load ('vokabeln.mat') ;
bild_org = imread('IMAG0460.jpg'); % Einlesen des Bildes
2.Schritt: Vorbereiten der Daten
Unter der Annahme eines rechteckigen Schildes welches sich gut von der Umgebung abhebt wird kann das Bild auf ein Kantenbild reduziert werden. Mit Hilfe dieser Reduzierung und der Trennung vom Hintergrund werden die Schild Informationen hervorgehoben.
%% Bilddaten umwandeln Ergebnis = Kanten Bild
bild_grau = rgb2gray(bild_org); % umwandeln des Bildes in ein Graustufenbild
bild_grau= imadjust(bild_grau); % Kontrast erhöhen
thresh = graythresh(bild_grau); % automatische Bestimmung eines Schwellenwertes, um Vorder- und Hintergrund zu unterscheiden
bild_bw = im2bw(bild_grau,thresh); % Umwandeln des Graustufenbildes in ein b/w-Bild in Abhängigkeit des vorherbestimmten Schwellenwertes
bild_bw_canny = edge(bild_bw, 'Canny'); % Kantenbild durch Canny
3.Schritt: Wichtige Region finden
%% Roi erzeugen / finden und Bild reduzieren
bild_bw_roi = imfill(bild_bw_canny,'holes');% Hier werden alle schwarzen Bereiche, die komlett von weißen Bereichen umgeben sind, auf weiß gesetzt und damit zu dem Objekt hinzugefügt
bild_bw_roi = bwareaopen(bild_bw_roi,6000,4);
bild_bw_roi = imfill(bild_bw_roi,'holes');
bild_grau_roi = bild_grau .* uint8(bild_bw_roi);% Grau bild auf ROI reduzieren
stats = regionprops(bild_bw_roi); % weiße Regionen finden
4.Schritt: Entzerrung der ROI
%% Transformation / Entzerung des Bildes
bild_bw_roi_sobel = edge(bild_bw_roi,'Sobel'); % kanten der Roi
% Koordinaten der BoundingBox Ecken ergeben die unverzerrte Ecken --> Näherung an die Originalgröße des Schildes da nicht bekannt
% Oben Links Ecke
corner_Bb{1} = [stats(1).BoundingBox(1,1),stats(1).BoundingBox(1,2)];
% oben Rechts Ecke
corner_Bb{2} = [stats(1).BoundingBox(1,1)+stats(1).BoundingBox(1,3) ,stats(1).BoundingBox(1,2)];
% Unten Rechts Ecke
corner_Bb{3} = [stats(1).BoundingBox(1,1)+stats(1).BoundingBox(1,3),stats(1).BoundingBox(1,2)+stats(1).BoundingBox(1,4)];
% Unten Links Ecke
corner_Bb{4} = [stats(1).BoundingBox(1,1),stats(1).BoundingBox(1,2)+stats(1).BoundingBox(1,4)];
% Geraden erzeugen um Ecken in der Perspektive zu berechnen
[H,theta,rho] = hough(bild_bw_roi_sobel); % Hough Transformation
P = houghpeaks(H,5,'threshold',ceil(0.2*max(H(:)))); % in der Hough Transformation Maxima finden
lines = houghlines(bild_bw_roi_sobel,theta,rho,P,'FillGap',150,'MinLength',20); % Linen finden
% Parallelen finden doppelte Linien aussortieren
if (size(lines,2)>4)
for cnt = 1 : size(lines,2)
lines_diff(cnt) = abs(lines(cnt).rho) - abs(lines(cnt).theta); % Differnz der Beiden Winkel erstellen um Gleich gerichtete Linen zu finden
end
for cnt = 1 : size(lines,2)
for cnt2 = cnt : size(lines,2)
lines_diff_each(cnt2,cnt)=min(abs(lines_diff(cnt)-lines_diff(cnt2))); % Alle Differenzen von einander Abziehen um Ähnlichkeit zu finden
end
end
[lines_diff_row,lines_diff_colum ]= find (lines_diff_each<40&lines_diff_each>0); % Doppelte linen löschen
lines(lines_diff_row)=[];
end
for cnt = 1 : size(lines,2)
lines_theta(cnt) = lines(cnt).theta ; % theta ist der Winkel zur Achse bei ähnlichem winkel sind die Linien Paralle
end
[b,ix] = sort(lines_theta);% Nach Größe sotieren
% Ecken berechnen aus den Schnittpunkten
corner{4} = schneide ([lines(ix(2)).point1(1,1);lines(ix(2)).point1(1,2)],...
[lines(ix(2)).point2(1,1);lines(ix(2)).point2(1,2)],...
[lines(ix(3)).point1(1,1);lines(ix(3)).point1(1,2)],...
[lines(ix(3)).point2(1,1);lines(ix(3)).point2(1,2)]);
corner{1} = schneide ([lines(ix(1)).point1(1,1);lines(ix(1)).point1(1,2)],...
[lines(ix(1)).point2(1,1);lines(ix(1)).point2(1,2)],...
[lines(ix(3)).point1(1,1);lines(ix(3)).point1(1,2)],...
[lines(ix(3)).point2(1,1);lines(ix(3)).point2(1,2)]);
corner{2} = schneide ([lines(ix(1)).point1(1,1);lines(ix(1)).point1(1,2)],...
[lines(ix(1)).point2(1,1);lines(ix(1)).point2(1,2)],...
[lines(ix(4)).point1(1,1);lines(ix(4)).point1(1,2)],...
[lines(ix(4)).point2(1,1);lines(ix(4)).point2(1,2)]);
corner{3} = schneide ([lines(ix(2)).point1(1,1);lines(ix(2)).point1(1,2)],...
[lines(ix(2)).point2(1,1);lines(ix(2)).point2(1,2)],...
[lines(ix(4)).point1(1,1);lines(ix(4)).point1(1,2)],...
[lines(ix(4)).point2(1,1);lines(ix(4)).point2(1,2)]);
[T,invT] = transformation_Ecken (corner_Bb,corner); % Umrechnung der gebenen ecken in Transformations Struckturen
bild_rgb_entzert =imtransform(bild_org,T,'XData',[1 size(bild_org,2)],'YData',[1 size(bild_org,1)]);% Transformation des Bildes
bild_grau_entzert = rgb2gray(bild_rgb_entzert);
bild_bw_entzert = im2bw(bild_grau_entzert,thresh);
5.Schritt: Texterkennung , Übersetzung und Reintegration
%% Text erkennung im entzerten Bild / Übersetzung und einfügen der Übersetzung ins Bild
text = ocr(bild_rgb_entzert,stats(1).BoundingBox); % Sucht nach Schrift in der ROI
schrift = text.Text;
for cnt = 1 : size(text.Words)
vokabel_englisch = text.Words(cnt,1);
% Im Wörterbuch nach Vokabel suchen
vokabel_ind = find(ismember(vokabeln,vokabel_englisch));
if vokabel_ind > 0
if vokabel_ind < size(vokabeln,1)
% Vokabel einfügen wenn im Wörter Buchvorhanden
vokabel_laenge = size (vokabeln{vokabel_ind,2},2);
% Länge der Übersetzung bestimmen umGröße der Buchstaben zu berechen
uebersetzungs_laenge = size (vokabeln{vokabel_ind,2},2);
% Größe der Buchstaben ind der breite berechen / Höhe übernehmen
breite_buchstaben = floor(text.WordBoundingBoxes(cnt,3)/uebersetzungs_laenge);
hoehe_buchstaben= text.WordBoundingBoxes(cnt,4);
% Bereich der Alten Wörter überdeken
% im BW Bild
bild_bw_entzert(text.WordBoundingBoxes(cnt,2):(text.WordBoundingBoxes(cnt,2)+text.WordBoundingBoxes(cnt,4)),...
text.WordBoundingBoxes(cnt,1):(text.WordBoundingBoxes(cnt,1)+text.WordBoundingBoxes(cnt,3)))= 0;
bild_grau_entzert = bild_grau_entzert.* uint8(bild_bw_entzert);
% Vokabel ins Bild einfügen
for cnt2 = 1 : vokabel_laenge
bild_buchstabe_ind = find(ismember(buchstabe(:,1),vokabeln{vokabel_ind,2}(cnt2)));
if bild_buchstabe_ind > 0
% Buchstaben auf Größe anpassen
buchstabe_uebersetzung = imresize(buchstabe{bild_buchstabe_ind,2},[hoehe_buchstaben breite_buchstaben]);
% Buchstaben ins Bild integrienen
bild_bw_entzert(text.WordBoundingBoxes(cnt,2):(text.WordBoundingBoxes(cnt,2)+hoehe_buchstaben)-1,...
text.WordBoundingBoxes(cnt,1)+cnt2*breite_buchstaben-breite_buchstaben:(text.WordBoundingBoxes(cnt,1)+cnt2*breite_buchstaben)-1)=buchstabe_uebersetzung;
% Buchstaben ins Bild integrienen
bild_grau_entzert(text.WordBoundingBoxes(cnt,2):(text.WordBoundingBoxes(cnt,2)+hoehe_buchstaben)-1,...
text.WordBoundingBoxes(cnt,1)+cnt2*breite_buchstaben-breite_buchstaben:(text.WordBoundingBoxes(cnt,1)+cnt2*breite_buchstaben)-1)= 255 * uint8(buchstabe_uebersetzung);
end
end
end
end
end
6.Schritt:Rücktransformation
%% Rücktransformation und anpassen des Bildes
bild_grau_verzert =imtransform(bild_grau_entzert,invT,'XData',[1 size(bild_org,2)],'YData',[1 size(bild_org,1)]); % rücktransformation des BW Bildes
Siehe auch
Weblinks
- YouTube: Introducing Word Lens
- Automatically Detect and Recognize Text in Natural Images - Matlab R2014a
→ zurück zum Hauptartikel: Digitale Signal- und Bildverarbeitung SoSe2014