Augmented Reality: Wörterbuch
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
%% 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