re-gliederung
This commit is contained in:
1
.vscode/ltex.dictionary.de-AT.txt
vendored
1
.vscode/ltex.dictionary.de-AT.txt
vendored
@@ -57,3 +57,4 @@ Hermite-Interpolation
|
||||
Nearest-Neighbor
|
||||
unimodalen
|
||||
Nachbearbeitungskette
|
||||
schlagwortbasierten
|
||||
|
||||
@@ -2,4 +2,5 @@
|
||||
\label{einleitung}
|
||||
|
||||
\input{chapters/c10_einleitung/motivation}
|
||||
\input{chapters/c10_einleitung/herausforderungen}
|
||||
\input{chapters/c10_einleitung/herausforderungen}
|
||||
\input{chapters/c10_einleitung/vorgehensweise}
|
||||
@@ -5,7 +5,26 @@ Die in Salzburg ansässige COPA-DATA GmbH bietet die Softwareplattform zenon an,
|
||||
|
||||
Die zenon-Plattform kann sowohl vom Kunden selbst, als auch durch das Professional Services Team individuell auf Kundenanforderungen zugeschnitten und in bestehende Prozesse eingebunden werden. Den Grundstein für die hohe Anpassungsfähigkeit bildet die Produktdokumentation, in der Schnittstellendokumentation, Anleitungen und Beispiele in verschiedensten Sprachen, Formaten und mit kundenspezifischen Erweiterungen umfassend sowohl für Mitarbeiter, als auch für Kunden festgehalten sind.
|
||||
|
||||
In der Produktdokumentation werden, besonders in Hinblick auf die grafischen Tools wie die zenon Engineering Studio Entwicklungsumgebung oder die zenon Service Engine, zahlreiche Grafiken verwendet, um Beispiele verständlicher zu machen und Anleitungen übersichtlicher zu gestalten. Um bei dem großen Funktionsumfang der zenon-Tools, den vielen Sprachen, Anpassungen und den unterschiedlichen Themengebieten innerhalb der Dokumentation nicht den Überblick zu verlieren, benötigt das interne "Technical Content and Translation" Team unterstützend zu dem intern verwendeten CMS eine dedizierte Anwendung zur Verwaltung von sprachabhängigen Bilddateien.
|
||||
In der Produktdokumentation werden, besonders in Hinblick auf die grafischen Tools wie die zenon Engineering Studio Entwicklungsumgebung oder die zenon Service Engine, zahlreiche Grafiken wie \autoref{annahmen_bild_eigenschaften_beispiel} verwendet, um Beispiele verständlicher zu machen und Anleitungen übersichtlicher zu gestalten. Um bei dem großen Funktionsumfang der zenon-Tools, den vielen Sprachen, Anpassungen und den unterschiedlichen Themengebieten innerhalb der Dokumentation nicht den Überblick zu verlieren, benötigt das interne "Technical Content and Translation" Team unterstützend zu dem intern verwendeten CMS eine dedizierte Anwendung zur Verwaltung von sprachabhängigen Bilddateien.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{minipage}{0.66\textwidth}
|
||||
\includegraphics[width=\textwidth]{include/screenshots/driver_brpvi_offlineimport_004.png}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.3\textwidth}
|
||||
\begin{minipage}{\textwidth}
|
||||
\includegraphics[width=\textwidth]{include/screenshots/historian_assistent_001.png}
|
||||
\end{minipage}\hfill
|
||||
\vfill
|
||||
\begin{minipage}{\textwidth}
|
||||
\includegraphics[width=\textwidth]{include/screenshots/driver_archdrv_variablendefinition_001.png}
|
||||
\end{minipage}\hfill
|
||||
\end{minipage}
|
||||
\caption{Beispielhafte Auswahl typischer Dialogscreenshots.}
|
||||
\label{annahmen_bild_eigenschaften_beispiel}
|
||||
\end{figure}
|
||||
|
||||
Während das Programm auch die Basisfunktionalität, das Speichern, Bearbeiten, Löschen, Abrufen beziehungsweise das generelle Verwalten von Screenshots und der zugehörigen Metainformation abdecken soll, konzentriert sich diese Bachelorarbeit primär auf die Kategorisierungsfunktionalität der Bildinhalte.
|
||||
|
||||
|
||||
4
chapters/c10_einleitung/vorgehensweise.tex
Normal file
4
chapters/c10_einleitung/vorgehensweise.tex
Normal file
@@ -0,0 +1,4 @@
|
||||
\section{Aufbau}
|
||||
\label{aufbau}
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
\chapter{Grundlagen}
|
||||
\label{Grundlagen}
|
||||
|
||||
\input{chapters/c20_grundlagen/stand_der_technik}
|
||||
\input{chapters/c20_grundlagen/technologien}
|
||||
Für einen technischen Überblick und als Grundlage für die Auswahl der innerhalb dieser Bachelorarbeit verwendeten Algorithmen, wird im folgenden Kapitel näher auf \hyperref[grundlagen_texterkennungssysteme]{Texterkennungssysteme}, Grundlagen zur \hyperref[grundlagen_preprocessing]{Vorverarbeitung}, \hyperref[grundlagen_postprocessing]{Nachbearbeitung} sowie die verwendeten \hyperref[metriken]{Metriken} zum Vergleich eingegangen.
|
||||
|
||||
\input{chapters/c20_grundlagen/texterkennungssysteme}
|
||||
\input{chapters/c20_grundlagen/preprocessing}
|
||||
\input{chapters/c20_grundlagen/postprocessing}
|
||||
\input{chapters/c20_grundlagen/metriken}
|
||||
@@ -1,16 +1,16 @@
|
||||
\subsection{Metriken}
|
||||
\section{Metriken}
|
||||
\label{metriken}
|
||||
|
||||
Um die erkannten Ergebnisse unter Verwendung der verschiedenen Pre- und Postprocessing Schritte mittels eines einheitlichen Systems vergleichen zu können, wird auf die in der optischen Texterkennung gängigen Metriken "Character Metric", auch bekannt als "Character Error Rate" und "Word metric" \bzw "Word Error Rate" \mcite{karpinski2018metrics}, basierend auf der Levenshtein-Distanz \mcite{levenshtein1966binary} zurückgegriffen.
|
||||
|
||||
Sowohl die Character- als auch die Word Error Rate sind häufig genutzte Vergleichswerte, die ihren Ursprung in der computergestützten Sprachverarbeitung \bzw automatischen Spracherkennung haben \mcite{wang2003word}. Da die optische Texterkennung und die automatische Spracherkennung jeweils darauf abzielen, maschinenlesbaren Text aus nicht-strukturierten Daten zu extrahieren, sind die Prinzipien dieser Metriken auch auf die optische Texterkennung anwendbar \mcite{tong1996statistical}.
|
||||
|
||||
\subsubsection{Word Error Rate}
|
||||
\subsection{Word Error Rate}
|
||||
\label{metriken_wer}
|
||||
|
||||
Die Wortfehlerrate (\engl{Word Error Rate}, \kurz{WER}) beschreibt den prozentualen Anteil der falsch erkannten oder fehlenden Wörter eines Textes im Vergleich zu einer Referenz, welche im Falle der folgenden Vergleiche immer alle sichtbaren Texte im Bild repräsentiert. Je niedriger die WER, desto genauer ist der OCR-Vorgang. Um die WER zu berechnen, bildet man die Summe aller notwendigen Ersetzungen, Entfernungen und Einfügungen, um aus dem erkannten Text den Referenztext bilden zu können und setzt sie mit der Gesamtwortanzahl im Referenztext in Verhältnis \mcite{levenshtein1966binary, park2008empirical, karpinski2018metrics}.
|
||||
|
||||
\subsubsubsection{Berechnung}
|
||||
\subsubsection{Berechnung}
|
||||
|
||||
Die mathematische Formel für die Word Error Rate lautet somit wie folgt \mcite{karpinski2018metrics}:
|
||||
|
||||
@@ -28,18 +28,18 @@ wobei die einzelnen Komponenten folgende Größen darstellen:
|
||||
\item \(N\) beschreibt die Gesamtanzahl der Wörter in der Referenz
|
||||
\end{itemize}
|
||||
|
||||
\subsubsubsection{Vorteile und Nachteile}
|
||||
\subsubsection{Vorteile und Nachteile}
|
||||
|
||||
Die WER spiegelt ohne großen Rechenaufwand direkt wider, wie stark die erkannten Texte der Referenz gleichen. Hierbei werden fehlerhafte Einsetzungen, Löschungen und falsch erkannte Wörter \bzw Teilwörter gleichermaßen gewichtet. Es ist jedoch nicht möglich, die korrekte Reihenfolge der erkannten Wörter darzustellen oder bestimmte wichtige Stellen im Text höher zu gewichten als andere. Zudem werden fehlerhaft erkannte Wörter als vollwertige Ersetzung wahrgenommen, auch wenn nur ein einzelnes Zeichen falsch ist. Dadurch wird das Ergebnis stark beeinflusst.
|
||||
|
||||
Um die Verfälschung der Ergebniswerte durch die WER möglichst gering zu halten, muss mindestens eine weitere Fehlermetrik, beispielsweise die \hyperref[metriken_cer]{Character Error Rate}, zum Vergleich verwendet werden.
|
||||
|
||||
\subsubsection{Character Error Rate}
|
||||
\subsection{Character Error Rate}
|
||||
\label{metriken_cer}
|
||||
|
||||
Die Zeichenfehlerrate (\engl{Character Error Rate}, \kurz{CER}) beschreibt die Anzahl der falsch erkannten oder fehlenden Zeichen im Vergleich zu einem Referenzwort und basiert wie die \hyperref[metriken_wer]{Word Error Rate} auf der Levenshtein-Distanz \mcite{levenshtein1966binary}. Je niedriger die CER, desto genauer ist der OCR-Vorgang. Ähnlich wie die WER wird die CER aus der Summe aller Ersetzungen, Entfernungen und Einfügungen, notwendig um aus dem erkannten Wort die Referenz bilden zu können, gebildet \mcite{levenshtein1966binary}. Diese Summe wird anschließend durch die Zeichananzahl des Referenzwortes geteilt \mcite{park2008empirical, karpinski2018metrics}.
|
||||
|
||||
\subsubsubsection{Berechnung}
|
||||
\subsubsection{Berechnung}
|
||||
|
||||
Das Verfahren zur Ermittlung der CER gleicht im Wesentlichen dem der WER. Die mathematische Formel lautet somit wie folgt \mcite{karpinski2018metrics}:
|
||||
|
||||
@@ -57,7 +57,7 @@ wobei die einzelnen Komponenten folgende Größen darstellen:
|
||||
\item \(N\) beschreibt die Gesamtanzahl der Zeichen in der Referenz
|
||||
\end{itemize}
|
||||
|
||||
\subsubsubsection{Vorteile und Nachteile}
|
||||
\subsubsection{Vorteile und Nachteile}
|
||||
|
||||
Die CER fasst in einem Wert zusammen, wie viele Änderungen auf Zeichenebene notwendig sind, um aus dem erkannten Wort das Referenzwort zu bilden. Es ist dabei wie bei der WER nicht relevant, in welcher Reihenfolge diese Zeichen auftreten. Ebenso gibt es keine gesonderte Gewichtung für Ersetzungen, Löschungen oder Einfügungen, wodurch besonders bei kurzen Wörtern auch kleinere Abweichungen bereits zu einer hohen CER führen können.
|
||||
|
||||
33
chapters/c20_grundlagen/postprocessing.tex
Normal file
33
chapters/c20_grundlagen/postprocessing.tex
Normal file
@@ -0,0 +1,33 @@
|
||||
\section{Nachbearbeitung}
|
||||
\label{grundlagen_postprocessing}
|
||||
|
||||
Das Themengebiet des Natural Language Processing beschäftigt sich mit der Interaktion zwischen menschlicher Sprache und Computern. Techniken aus der Informatik, Linguistik und dem maschinellen Lernen werden kombiniert, um mit menschlicher Sprache umzugehen und beispielsweise Textanalyse, Übersetzungen, Spracherkennung oder Dialogsysteme möglich zu machen \mcite{chowdhary2020natural}. Durch die große Aufmerksamkeit und die vielseitige Nutzung der Technologien -- von automatischer Rechtschreibkontrolle bis hin zu digitalen Sprachassistenten -- sowie dem Aufkommen von neuronalen Netzwerken wurden in diesem Forschungsgebiet immer wieder Fortschritte erzielt \mcite{kalyanathaya2019advances, church1995}
|
||||
|
||||
Dadurch gibt es zahlreiche wissenschaftliche Ressourcen, die als Grundlage für die Vorgehensweise zur Interpretation und Extraktion relevanter Schlagworte aus den erkannten Freitextdaten dienen.
|
||||
|
||||
\subsection{Schlagworte}
|
||||
\label{grundlagen_schlagworte}
|
||||
|
||||
Für die spätere Suche von Screenshots sollen relevante Schlagworte aus den erkannten Textdaten extrahiert werden. Ein Wort eignet sich dann als Schlagwort, wenn es in relevantem Bezug zum jeweiligen Bild steht und dabei eine wichtige Aktion oder Information widerspiegelt. Inhalte, die direkt in der grafischen Benutzeroberfläche ersichtlich sind, haben daher einen hohen Informationsgehalt und eignen sich besonders gut als Suchworte. Um die Schlagwortmenge so aussagekräftig wie möglich zu halten, müssen Wörter mit geringer Bedeutung entfernt werden. Beispielsweise haben sogenannte Stoppwörter (\engl{Stop words}) wie \textit{und} oder \textit{oder} keine besondere Semantik und fördern aufgrund ihrer Häufigkeit das Auftreten von Verwechslungen \mcite{wilbur1992automatic}.
|
||||
|
||||
\subsection{Mehrsprachigkeit}
|
||||
\label{grundlagen_mehrsprachigkeit}
|
||||
|
||||
Das Textverarbeitungssystem muss in der Lage sein, mehrsprachige Bilddateien einlesen und interpretieren zu können. So sollen beispielsweise Bilder mit englischen, deutschen oder italienischen Inhalten zugeführt und die Ergebnisdaten richtig verarbeitet werden können. Um eine Filterung für verschiedene Zeichensätze zu ermöglichen und eine Unterstützung für Sprachen mit nicht-lateinischen Schriften zu gewährleisten, werden dynamische Sprachfilter verwendet, die individuell an die jeweilige Sprache angepasst werden können. Für die weitere Beschreibung der generellen Vorgehensweise und Tests werden in den folgenden Schritten jedoch nur deutsche oder englische Inhalte verwendet.
|
||||
|
||||
\subsubsection{Filtern von Symbolen}
|
||||
|
||||
Bei der Texterkennung kann es vorkommen, dass grafische Elemente als diverse Unicode-Symbole erkannt werden. Wie in \autoref{fig:screenshot_postprocessing}, wird oftmals versucht, grafische Dekorationselemente textuell nachzubilden. Auch finden sich in den ungefilterten Ergebnisdaten oft Aufzählungszeichen wie "•" oder unterschiedliche Varianten von Bindestrichen "‒". Diese Zeichen sind gemäß Anwendungsanforderungen nicht relevant für die Schlagwortsuche und können somit entfernt \bzw ignoriert werden.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{minipage}{0.45\textwidth}
|
||||
\includegraphics[width=0.90\textwidth]{include/postprocessing/source.png}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\lstinputlisting[firstnumber=100,linerange={100-110}]{include/postprocessing/source.json}
|
||||
\end{minipage}
|
||||
\caption{Auszug aus den ungefilterten Ergebnisdaten bei Durchführung der Texterkennung in dem gezeigten Screenshot.}
|
||||
\label{fig:screenshot_postprocessing}
|
||||
\end{figure}
|
||||
23
chapters/c20_grundlagen/preprocessing.tex
Normal file
23
chapters/c20_grundlagen/preprocessing.tex
Normal file
@@ -0,0 +1,23 @@
|
||||
\section{Vorverarbeitung}
|
||||
\label{grundlagen_preprocessing}
|
||||
|
||||
Für optimale OCR-Ergebnisse ist es notwendig, die zu verarbeitenden Bilddaten zunächst für die Texterkennung vorzubereiten.
|
||||
|
||||
\subsection{Eigenschaften von Screenshots}
|
||||
\label{grundlagen_bild_eigenschaften}
|
||||
|
||||
Die zu verarbeitenden Bilder im Kontext dieser Bachelorarbeit sind ausschließlich digitale Bildschirmaufnahmen von grafischen Benutzeroberflächen. Es kann also angenommen werden, dass die Screenshots keine Transparenz aufweisen, die Perspektive der Aufnahme nicht verzerrt ist und im Normalfall nicht mit Bildrauschen zu rechnen ist, weshalb Rauschfilterung \mcite{kumar2017noise} nicht notwendig ist. Auch der Kontrast ist in den meisten Fällen ausreichend, um die relevanten Inhalte zu erkennen. Weiters ist bei der Bildverarbeitung auf farbige Hintergrundflächen zu achten, mit deren Unterstützung Bildschirmelemente in modernen grafischen Oberflächen oft markiert, gruppiert oder getrennt werden. Nach Sichtung des zu verarbeitenden Bilddatensatzes fällt auf, dass manche Screenshots durch das Selektieren mit der Maus sehr eng abgeschnitten wurden. Das ist bei dem Preprocessing ebenfalls zu berücksichtigen. Eine beispielhafte Auswahl typischer Screenshots findet sich in \autoref{grundlagen_bild_eigenschaften_beispiel}.
|
||||
|
||||
\subsection{Optimieren von Daten für Tesseract}
|
||||
\label{grundlagen_bild_optimal}
|
||||
|
||||
Für die Verwendung von Tesseract ist es wichtig, unabhängig von der Diversität der Ausgangsdaten möglichst einheitliche Bilder zu erzeugen \mcite{tessdoc}. Während störende Elemente wie Bildrauschen aus dem Bild entfernt werden, sollen Texte ohne Einfluss der eigentlichen Hinter- bzw. Vordergrundfarbe gut zu erkennen sein. Auch eine deutliche Abgrenzung von Formen oder grafischen Symbolen ist von großer Wichtigkeit \mcite{sporici2020improving} \mcite{mursari2021effectiveness}. Wie in \autoref{fig:screenshot_comparison_optimal} gezeigt, sollen farbige Hintergrundflächen und grafische Dekorationselemente verschwinden. Übrig bleibt optimalerweise nur der gut lesbare textuelle Inhalt des Bildes.
|
||||
|
||||
\begin{figure}[hb]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=0.45\textwidth]{include/screenshots/command-processing_screentypes_controlgroup_005.png}}
|
||||
\hfill
|
||||
\fbox{\includegraphics[width=0.45\textwidth]{\detokenize{include/results/ThresholdProcessor(40\%).00.command-processing_screentypes_controlgroup_005.png}}}
|
||||
\caption{Ein optimales Ergebnisbild. Jegliche farblichen Flächen wurden durch die Bildverarbeitung entfernt. Übrig bleibt klar lesbarer Text mit einem hohen Kontrast zum Hintergrund.}
|
||||
\label{fig:screenshot_comparison_optimal}
|
||||
\end{figure}
|
||||
@@ -1,14 +0,0 @@
|
||||
\section{Stand der Technik}
|
||||
\label{technik}
|
||||
|
||||
\subsection{Texterkennungssysteme}
|
||||
|
||||
Optische Texterkennung wird in der Informationstechnik eingesetzt, um Textinhalte aus gedruckten oder digital rasterisierten Medien zu extrahieren. Dieses Verfahren kann für diverse Anwendungsgebiete genutzt werden, wie beispielsweise für Handschrifterkennung \mcite{rakshit2010recognition} oder für das Ablesen von Nummernschildern eines Autos \mcite{asif2014overview, anyline_home}. Auf dem Markt gibt es dafür bereits viele kommerzielle Komplettlösungen wie "Anyline" \mcite{anyline_home}, "IronOCR" \mcite{ironocr_home}, "Google Cloud Vision" \mcite{gcv_home}, "Amazon Textract" \mcite{textract_home} oder "Microsoft Azure Computer Vision" \mcite{azurevision_home}, die oftmals gute Ergebnisse mit geringen Fehlerraten erzielen und sich in bestehende Prozesse oder Anwendungen integrieren lassen \mcite{the_old_bailey_and_ocr, cc_platforms_comparison}.
|
||||
|
||||
Heutige Texterkennungssysteme arbeiten oft mit einer Kombination aus neuralen Netzwerken und fortgeschrittenen Bildverarbeitungsalgorithmen, um Texte zu erkennen. Zahlreiche wissenschaftliche Werke wie beispielseweise \mcite{eikvil1993optical} oder \mcite{islam2017survey} erklären die grundlegende Funktionsweise von optischen Texterkennungswerkzeugen. Die genauen Schritte zur richtigen Vorbereitung der Bilddaten -- besonders in Bezug auf Screenshots -- werden jedoch oftmals nur oberflächlich behandelt.
|
||||
|
||||
\subsection{Filterung der Ergebnisdaten}
|
||||
|
||||
Das Themengebiet des Natural Language Processing beschäftigt sich mit der Interaktion zwischen menschlicher Sprache und Computern. Techniken aus der Informatik, Linguistik und dem maschinellen Lernen werden kombiniert, um mit menschlicher Sprache umzugehen und beispielsweise Textanalyse, Übersetzungen, Spracherkennung oder Dialogsysteme möglich zu machen \mcite{chowdhary2020natural}. Durch die große Aufmerksamkeit und die vielseitige Nutzung der Technologien -- von automatischer Rechtschreibkontrolle bis hin zu digitalen Sprachassistenten -- sowie dem Aufkommen von neuronalen Netzwerken wurden in diesem Forschungsgebiet immer wieder Fortschritte erzielt \mcite{kalyanathaya2019advances, church1995}
|
||||
|
||||
Dadurch gibt es zahlreiche wissenschaftliche Ressourcen, die als Grundlage für die Vorgehensweise zur Interpretation und Extraktion relevanter Schlagworte aus den erkannten Freitextdaten dienen.
|
||||
@@ -1,12 +0,0 @@
|
||||
\section{Verwendete Technologien}
|
||||
\label{technologien}
|
||||
|
||||
\subsection{Texterkennungssystem}
|
||||
\label{texterkennungssystem}
|
||||
|
||||
Die Nutzung der in \autoref{einleitung} erwähnten Anwendungen \bzw Dienstleistungen ist kostenpflichtig und die genaue innere Vorgehensweise dieser Programme ist nicht öffentlich bekannt \mcite{textract_pricing, gcv_pricing, azurevision_pricing}. Aufgrund dieser Tatsachen ist die Wahl des Texterkennungssystems für die prototypische Implementierung dieser Bachelorarbeit auf die seit 2005 unter der Freie-Software-Lizenz "Apache 2.0" veröffentlichten "Tesseract Open Source OCR Engine" (kurz: Tesseract) gefallen \mcite{Smith2007}. Diese basiert seit der Major-Version 4 auf einem neuronalen Netz, durch welches mithilfe von sprachspezifischen Trainingsdaten Texte in Bildern erkannt werden können \mcite{tessdoc}.
|
||||
|
||||
\subsection{Bildbearbeitungswerkzeug}
|
||||
\label{bildbearbeitungswerkzeug}
|
||||
|
||||
Als Werkzeug für die Durchführung der notwendigen Bildbearbeitungsschritte wurde aufgrund persönlicher Erfahrungen die Softwarebibliothek "ImageMagick" \mcite{imagemagick} gewählt. Sie ist umfassend dokumentiert, flexibel und kann Dank der Unterstützung für eine Vielzahl von Programmiersprachen direkt in Programme eingebunden werden. Viele in der Bildverarbeitung genutzte Operationen sind bereits implementiert, was schnelles Prototyping vereinfacht. Dadurch ist die Bibliothek eine ideale Wahl für die Realisierung von Bildbearbeitungsschritten in der prototypischen Implementierung, sie kann jedoch auch durch eine andere Implementierung ersetzt werden.
|
||||
9
chapters/c20_grundlagen/texterkennungssysteme.tex
Normal file
9
chapters/c20_grundlagen/texterkennungssysteme.tex
Normal file
@@ -0,0 +1,9 @@
|
||||
\section{Überblick Texterkennungssysteme}
|
||||
\label{grundlagen_texerkennungssysteme}
|
||||
|
||||
Optische Texterkennung wird in der Informationstechnik eingesetzt, um Textinhalte aus gedruckten oder digital rasterisierten Medien zu extrahieren. Dieses Verfahren kann für diverse Anwendungsgebiete genutzt werden, wie beispielsweise für Handschrifterkennung \mcite{rakshit2010recognition} oder für das Ablesen von Nummernschildern eines Autos \mcite{asif2014overview, anyline_home}. Auf dem Markt gibt es dafür bereits viele kommerzielle Komplettlösungen wie "Anyline" \mcite{anyline_home}, "IronOCR" \mcite{ironocr_home}, "Google Cloud Vision" \mcite{gcv_home}, "Amazon Textract" \mcite{textract_home} oder "Microsoft Azure Computer Vision" \mcite{azurevision_home}, die oftmals gute Ergebnisse mit geringen Fehlerraten erzielen und sich in bestehende Prozesse oder Anwendungen integrieren lassen \mcite{the_old_bailey_and_ocr, cc_platforms_comparison}.
|
||||
|
||||
Besonders Open-Source-Software zur Texterkennung erfreut sich großer Beliebtheit. So verfügt das GitHub-Repository der "Tesseract Open Source OCR Engine" (kurz: Tesseract) derzeit neben über 56000 Sternen auf GitHub auch über eine aktive Community, die das Projekt ständig weiterentwickelt \mcite{tessrepo}. Tesseract ist seit 2005 unter der Freie-Software-Lizenz "Apache 2.0" lizenziert \mcite{Smith2007} und basiert seit der Major-Version 4 auf einem neuronalen Netz, durch welches mithilfe von sprachspezifischen Trainingsdaten Texte in Bildern erkannt werden können \mcite{tessdoc}.
|
||||
|
||||
Heutige Texterkennungssysteme arbeiten oft mit einer Kombination aus neuralen Netzwerken und fortgeschrittenen Bildverarbeitungsalgorithmen, um Texte zu erkennen. Zahlreiche wissenschaftliche Werke wie beispielsweise \mcite{eikvil1993optical} oder \mcite{islam2017survey} erklären die grundlegende Funktionsweise von optischen Texterkennungswerkzeugen. Die genauen Schritte zur richtigen Vorbereitung der Bilddaten -- besonders in Bezug auf Screenshots -- werden jedoch oftmals nur oberflächlich behandelt.
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
\section{Verwendete Algorithmen}
|
||||
\label{algorithmen}
|
||||
|
||||
\input{chapters/c30_konzept/algorithmen/preprocessing}
|
||||
\pagebreak
|
||||
\input{chapters/c30_konzept/algorithmen/postprocessing}
|
||||
@@ -1,10 +1,9 @@
|
||||
\pagebreak
|
||||
\subsection{Nachbearbeitung}
|
||||
\section{Algorithmen zur Nachbearbeitung}
|
||||
\label{algorithmen_postprocessing}
|
||||
|
||||
Die extrahierten Textdaten aus den verarbeiteten Bilddaten werden später in einer schlagwortbasierten Suchfunktion verwendet. Um Redundanz innerhalb des Datensets zu reduzieren und falsch erkannte Ergebnisdaten zu verhindern, müssen die Ergebnisdaten der Texterkennung im Rahmen des Postprocessings weiterverarbeitet werden.
|
||||
Die extrahierten Textdaten aus den verarbeiteten Bilddaten werden später in einer schlagwortbasierten Suchfunktion verwendet. Um Redundanz innerhalb des Datensets zu reduzieren und falsch erkannte Ergebnisdaten zu verhindern, müssen die Ergebnisdaten der Texterkennung im Rahmen der Nachbearbeitung (\engl{Postprocessing}) gemäß \autoref{annahmen_postprocessing} weiterverarbeitet werden.
|
||||
|
||||
\subsubsection{Filterung anhand der Genauigkeit}
|
||||
\subsection{Filterung anhand der Genauigkeit}
|
||||
\label{algorithmen_confidence}
|
||||
|
||||
Tesseract stellt im Rahmen der Texterkennung neben den erkannten Texten auch die jeweiligen Metadaten zur Verfügung. Auch die geschätzte Genauigkeit (\engl{Confidence}) wird für jedes erkannte Wort mit angegeben. Sie bestimmt, mit welcher Sicherheit ein Texterkennungssystem das jeweilige Wort erkannt hat, wobei Wörter mit hoher Confidence eher richtig, mit niedriger Confidence eher falsch erkannt wurden.
|
||||
@@ -24,7 +23,7 @@ Wie in \autoref{fig:screenshot_postprocessing_confidence} gezeigt, prüft der Co
|
||||
\label{fig:screenshot_postprocessing_confidence}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Normalisierung}
|
||||
\subsection{Normalisierung}
|
||||
\label{algorithmen_normalisierung}
|
||||
|
||||
Um die aus der Texterkennung gewonnenen Daten zunächst für die weitere Filterung vorzubereiten, ist es sinnvoll, die Redundanz der Daten möglichst zu reduzieren und die einzelnen Wörter zu normalisieren \bzw zu standardisieren. Beispielsweise kann durch das Umwandeln aller Textdaten in Kleinbuchstaben die Variation der Daten eingeschränkt werden, ohne jedoch für die Suche relevante Information zu verlieren. Diese Methode wurd auch in \autoref{fig:screenshot_postprocessing_normalisierung} angewandt.
|
||||
@@ -42,7 +41,7 @@ Um die aus der Texterkennung gewonnenen Daten zunächst für die weitere Filteru
|
||||
\label{fig:screenshot_postprocessing_normalisierung}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Vermeidung von Duplikaten}
|
||||
\subsection{Vermeidung von Duplikaten}
|
||||
\label{algorithmen_duplikate}
|
||||
|
||||
Nach der Normalisierung werden Duplikate innerhalb der erkannten Textdaten entfernt, um die Effizienz der nachfolgenden Filterverfahren zu erhöhen. In den Daten aus \autoref{fig:screenshot_postprocessing_duplikate} wird die Liste an erkannten Wörtern stark gekürzt und die Redundanz damit verringert. Es treten keine Duplikate mehr auf.
|
||||
@@ -60,7 +59,7 @@ Nach der Normalisierung werden Duplikate innerhalb der erkannten Textdaten entfe
|
||||
\label{fig:screenshot_postprocessing_duplikate}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Filterung anhand der Wortlänge}
|
||||
\subsection{Filterung anhand der Wortlänge}
|
||||
\label{algorithmen_wortlänge}
|
||||
|
||||
Verarbeitet das Texterkennungssystem Texte mit unregelmäßigen Abständen oder grafischen Artefakten in der Schrift, werden statt des eigentlichen Wortes fälschlicherweise oft kurze Symbolkombinationen erkannt. Um diese Kombinationen aus den Ergebnisdaten zu entfernen, können Zeichenketten, wie in \autoref{fig:screenshot_postprocessing_wortlänge} gezeigt, mithilfe des Wortlängenfilters ungeachtet ihres Inhaltes verworfen werden.
|
||||
@@ -80,7 +79,7 @@ Zusätzlich kann dieser Filter an die Anforderung des Zielsystems angepasst werd
|
||||
\label{fig:screenshot_postprocessing_wortlänge}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Sprachabhängige Filterung mittels Regular Expressions}
|
||||
\subsection{Sprachabhängige Filterung mittels Regular Expressions}
|
||||
\label{algorithmen_regex}
|
||||
|
||||
Nachdem die zu filternden Textdaten durch vorherige Schritte vorverarbeitet wurden, werden die Ergebnisdaten ein letztes Mal mithilfe von regulären Ausdrücken (\engl{Regular Expressions}) durchsucht. Aufgrund der dynamischen Erweiterbarkeit der Regular Expressions kann für jede Sprache ein individueller Filter angelegt werden, der den jeweiligen Zeichensatz beschriftet und unbekannte Sonderzeichen oder Symbole entfernt. So sind beispielsweise im Deutschen Umlaute erlaubt, während häufig auftretende, jedoch unerwünschte Symbole wie das phonetische Zeichen "æ" oder mehrere hintereinandergereihte Leerzeichen explizit entfernt werden können. Die Anwendung des deutschen Sprachfilters wird in \autoref{fig:screenshot_postprocessing_regex} gezeigt.
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
\subsection{Vorverarbeitung}
|
||||
|
||||
\section{Algorithmen zur Vorverarbeitung}
|
||||
\label{algorithmen_preprocessing}
|
||||
|
||||
Beim sogenannten "Preprocessing" werden die zu verarbeitenden Bilder für die Texterkennung vorbereitet, um die Qualität der erkannten Textdaten zu verbessern.
|
||||
Wie bereits in \autoref{annahmen_preprocessing} beschrieben, werden die zu verarbeitenden Bilder bei der Vorverarbeitung (\engl{Preprocessing}) für die Texterkennung vorbereitet, um die Qualität der erkannten Textdaten zu verbessern.
|
||||
|
||||
Verwendet man moderne Tesseract-Implementierungen, sind in diesen oft bereits rudimentäre Bildverarbeitungswerkzeuge verfügbar \mcite{tessdoc}. Mit diesen Werkzeugen werden die eingespeisten Bilder -- sofern nicht bereits im richtigen Format -- automatisch für die Texterkennung vorbereitet. Ohne weitere Einstellungen zu treffen, bewirkt diese Bildverarbeitung ein Umwandeln der Eingangsgrafiken in ein meist gut für Tesseract geeignetes Bild. Es ist jedoch zu beachten, dass die Bildverarbeitungsschritte individuell auf die erwarteten Eingangsdaten anzupassen sind. So können die Bilddaten den in \autoref{annahmen_bild_optimal} definierten optimalen Tesseract-Eingangsdaten angenähert werden.
|
||||
|
||||
Die folgenden Preprocessing-Schritte basieren auf der empfohlenen Vorgehensweise zur Verbesserung der Output-Qualität laut Tesseract-Dokumentation \mcite{tessdoc}. Gemäß den obigen Annahmen werden jedoch weder perspektivische Fehler, noch ein eventuelles Rauschen korrigiert. Konkret werden folgende Bildverarbeitungsschritte verglichen:
|
||||
|
||||
\subsubsection{Resampling}
|
||||
\subsection{Resampling}
|
||||
\label{algorithmen_resampling}
|
||||
|
||||
Bei Resampling wird die Bildauflösung durch Interpolation verändert. Interpolation beschreibt die Methode, fehlende Pixelwerte zwischen bekannten Punkten mittels eines festgelegten Verfahrens zu ergänzen. Abhängig vom gewählten Verfahren ist das Ergebnis meist ein glattes und kontinuierliches Bild. Um die für Tesseract optimale Mindestauflösung von 300 dpi \mcite{tessdoc} zu gewährleisten, muss das Eingangsbild, sofern es die Mindestauflösung unterschreitet, zunächst entsprechend vergrößert werden.
|
||||
@@ -37,7 +38,7 @@ Da Tesseract auf klare und scharfe Kontraste angewiesen ist, um Text korrekt zu
|
||||
|
||||
Nach einigen Tests fällt auf, dass Bilder, die mittels des Spline-Verfahrens \mcite{briand2018theory,unser1999splines} oder der Hermite-Interpolation \mcite{seta2009digital} skaliert wurden, weiche Konturen ohne harte Farbübergänge aufweisen. Tesseract profitiert jedoch stark von klaren Texten und hohen Kontrasten, weswegen diese Art des Resamplings keine ideale Basis für das Preprocessing bietet. Deswegen wird für die weiteren Schritte die Interpolation nach Lanczos \mcite{fadnavis2014image} für das Resampling verwendet.
|
||||
|
||||
\subsubsection{Rahmen}
|
||||
\subsection{Rahmen}
|
||||
\label{algorithmen_rahmen}
|
||||
|
||||
Befindet sich Text zu nah am Rand des Bildes, wird dieser nicht immer richtig erkannt. Ebenso kann auch ein zu großer einfärbiger Rahmen am Rand des Bildes die Texterkennung stören. Bei Rahmengrößen wie in \autoref{fig:rahmen_groß} kommt es vor, dass Bildsektionen fälschlicherweise als "leer" erkannt und übersprungen werden, wodurch der zu erkennende Text nicht in die Ergebnisdaten mit aufgenommen wird.
|
||||
@@ -49,10 +50,10 @@ Befindet sich Text zu nah am Rand des Bildes, wird dieser nicht immer richtig er
|
||||
\label{fig:rahmen_groß}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Binarisierung}
|
||||
\subsection{Binarisierung}
|
||||
\label{algorithmen_binarisierung}
|
||||
|
||||
Das Erzeugen eines Binärbildes ist durch Anwendung von Segmentierungsverfahren möglich. Schwellenwertverfahren (\engl{Thresholding}) bilden eine Untergruppe der Segmentierungsverfahren und werden genutzt, um Graustufenbilder Pixel für Pixel in binarisierte Ergebnisbilder mit zwei Segmenten, also einem Vordergrund und einem Hintergrund umzuwandeln. Der dazu notwendige Schwellenwert kann entweder fest definiert oder anhand von verschiedensten Algorithmen automatisch \bzw halbautomatisch ermittelt werden. Ziel ist es, durch die Binarisierung textuelle Bildinhalte unabhängig von der eigentlichen Vorder- und Hintergrundfarbe mit ausreichendem Kontrast darzustellen. Dadurch ist das Texterkennungssystem in der Lage, die einzelnen Textelemente und deren Inhalte besser zu identifizieren und zu verarbeiten. ImageMagick bietet eine Vielzahl an Thresholding-Algorithmen, von denen in \autoref{vergleich} folgende verglichen werden:
|
||||
Das Erzeugen eines Binärbildes ist durch Anwendung von Segmentierungsverfahren möglich. Schwellenwertverfahren (\engl{Thresholding}) bilden eine Untergruppe der Segmentierungsverfahren und werden genutzt, um Graustufenbilder Pixel für Pixel in binarisierte Ergebnisbilder mit zwei Segmenten, also einem Vordergrund und einem Hintergrund umzuwandeln. Der dazu notwendige Schwellenwert kann entweder fest definiert oder anhand von verschiedensten Algorithmen automatisch \bzw halbautomatisch ermittelt werden. Ziel ist es, durch die Binarisierung textuelle Bildinhalte unabhängig von der eigentlichen Vorder- und Hintergrundfarbe mit ausreichendem Kontrast darzustellen. Dadurch ist das Texterkennungssystem in der Lage, die einzelnen Textelemente und deren Inhalte besser zu identifizieren und zu verarbeiten. ImageMagick bietet eine Vielzahl an Thresholding-Algorithmen, von denen im Folgenden jene ausgewählt wurden:
|
||||
|
||||
\begin{itemize}
|
||||
\item Feste Schwellenwertmethode
|
||||
@@ -62,7 +63,7 @@ Das Erzeugen eines Binärbildes ist durch Anwendung von Segmentierungsverfahren
|
||||
\item Schwellenwertmethode nach Kapur
|
||||
\end{itemize}
|
||||
|
||||
\subsubsubsection{Feste Schwellenwertmethode}
|
||||
\subsection{Feste Schwellenwertmethode}
|
||||
\label{thresholding_fixed}
|
||||
|
||||
Ein häufig für die Bildsegmentierung genutztes Verfahren ist die feste Schwellenwertmethode, im Englischen auch "Fixed Thresholding" genannt. Bei diesem Bildverarbeitungsverfahren wird ein manuell vordefinierter Grenzwert auf das gesamte Bild angewandt. Liegt ein Pixelwert über dem festgelegten Schwellenwert, gilt dieser als Teil des Vordergrunds, andernfalls als Hintergrund \mcite{sahoo1988survey}. Somit können Objekte, also die einzelnen Buchstaben in den Grafikdateien, von ihrem Hintergrund getrennt werden.
|
||||
@@ -87,7 +88,7 @@ Das fixe Schwellenwertfahren benötigt durch den fest definierten Schwellenwert
|
||||
\label{thresholding_fixed_vergleich_schlecht}
|
||||
\end{figure}
|
||||
|
||||
\subsubsubsection{Adaptive Schwellenwertmethode}
|
||||
\subsection{Adaptive Schwellenwertmethode}
|
||||
\label{thresholding_adaptive}
|
||||
|
||||
Die adaptive Schwellenwertmethode gehört zu den halbautomatischen Schwellenwertalgorithmen. Bei diesem Verfahren wird der Schwellenwert auf Basis der lokalen Eigenschaften eines Bildbereichs angepasst, der durch die manuell festgelegte sogenannte "Blockgröße" definiert wird. Diese bestimmt die Seitenlänge des Rechtecks, innerhalb dessen ein fester Schwellenwert ermittelt wird \mcite{sahoo1988survey}. Durch diese dynamische Berechnung können im Gegensatz zur \hyperref[thresholding_fixed]{festen Schwellenwertmethode} verschiedenfarbige Texte auf Hintergründen unterschiedlicher Helligkeit besser abgegrenzt werden und die Menge an erkanntem Text wird erhöht, wie in \autoref{thresholding_adaptive_vergleich_gut} ersichtlich. Wird die Blockgröße falsch gewählt, können jedoch Artefakte auftreten, welche bei entsprechender Menge, wie im Falle von \autoref{thresholding_adaptive_vergleich_schlecht}, die Texterkennung negativ beeinflusst.
|
||||
@@ -111,12 +112,11 @@ Die adaptive Schwellenwertmethode gehört zu den halbautomatischen Schwellenwert
|
||||
\label{thresholding_adaptive_vergleich_schlecht}
|
||||
\end{figure}
|
||||
|
||||
\subsubsubsection{Dreiecks-Schwellenwertmethode}
|
||||
\subsection{Dreiecks-Schwellenwertmethode}
|
||||
\label{thresholding_triangle}
|
||||
|
||||
Das Dreiecks-Schwellenwertverfahren verwendet die Häufigkeitsverteilung der Helligkeitswerte eines Bildes, um einen globalen Schwellenwert zu ermitteln \mcite{zack1977automatic}. Werden diese Helligkeitswerte in einem Diagramm dargestellt, spricht man von einem Histogramm, wie in \autoref{unimodal_histogram} zu sehen. Für dieses Schwellenwertverfahren wird innerhalb des Histogramms eine Linie vom Höchstwert (\engl{Peak}) zum Minimum gezeichnet und die Normale mit der maximalen Länge ermittelt. Dieses Verfahren erzielt die besten Ergebnisse, wenn die zu extrahierenden Elemente Intensitätswerte aufweisen, die an der Basis des ermittelten Peaks liegen. Für Screenshots von UI-Elementen mit komplexer Struktur und farblich stark variierenden Komponenten ist es eher nicht geeignet.
|
||||
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=0.49\textwidth]{include/images_external/unimodal-histogram.png}}
|
||||
@@ -142,7 +142,7 @@ Das Dreiecks-Schwellenwertverfahren verwendet die Häufigkeitsverteilung der Hel
|
||||
\label{thresholding_triangle_vergleich_schlecht}
|
||||
\end{figure}
|
||||
|
||||
\subsubsubsection{Schwellenwertmethode nach Otsu}
|
||||
\subsection{Schwellenwertmethode nach Otsu}
|
||||
\label{thresholding_otsu}
|
||||
|
||||
Das Schwellenwertverfahren nach Otsu ermittelt einen globalen Schwellenwert durch Einteilung des Bildes in zwei Klassen (Vordergrund und Hintergrund). Dazu wird für jede Position des Schwellenwerts im Histogramm die Varianz der beiden dadurch entstehenden Klassen ermittelt. Der Schwellenwert ist dann optimal, wenn die Varianz der jeweiligen Klassen minimal ist \mcite{otsu1979threshold}. Aufgrund dieser Eigenschaften funktioniert das Verfahren am besten, wenn das Histogramm des Bildes wie in \autoref{bimodal_histogram} eine bimodale Verteilung aufweist, also zwei klare Spitzen hat.
|
||||
@@ -174,7 +174,7 @@ Enthält ein Bild jedoch starkes Hintergrundrauschen oder weist es lokale Hellig
|
||||
\label{thresholding_otsu_vergleich_schlecht}
|
||||
\end{figure}
|
||||
|
||||
\subsubsubsection{Schwellenwertmethode nach Kapur}
|
||||
\subsection{Schwellenwertmethode nach Kapur}
|
||||
\label{thresholding_kapur}
|
||||
|
||||
Die Schwellenwertmethode nach Kapur, Sahoo und Wong \mcite{kapur1985new} zielt darauf ab, einen Schwellenwert zu finden, der die Entropie zwischen den Vorder- und Hintergrundregionen maximiert. Wie in \autoref{thresholding_kapur_vergleich_gut} und \autoref{thresholding_kapur_vergleich_schlecht} zu sehen, liefert die Verwendung dieses Schwellenwertverfahrens gute Ergebnisse bei Bildern mit starker Varianz der Vorder- und Hintergrundkontraste \bzw einer breiten Helligkeitsverteilung.
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
\section{Annahmen}
|
||||
\label{annahmen}
|
||||
|
||||
Um die Texterkennung mittels Tesseract und die anschließende Filterung der Ergebnisdaten zu verbessern, werden anwendungsspezifische Annahmen für den Verarbeitungsablauf festgelegt.
|
||||
|
||||
\subsection{Vorverarbeitung}
|
||||
\label{annahmen_preprocessing}
|
||||
|
||||
\subsubsection{Eigenschaften von Screenshots}
|
||||
\label{annahmen_bild_eigenschaften}
|
||||
|
||||
Die zu verarbeitenden Bilder im Kontext dieser Bachelorarbeit sind ausschließlich digitale Bildschirmaufnahmen von grafischen Benutzeroberflächen. Es kann also angenommen werden, dass die Screenshots keine Transparenz aufweisen, die Perspektive der Aufnahme nicht verzerrt ist. Im Großteil der evaluierten Fälle ist auch der Kontrast ausreichend, um die relevanten Inhalte zu erkennen. Weiters ist bei der Bildverarbeitung auf farbige Hintergrundflächen zu achten, mit deren Unterstützung Bildschirmelemente in modernen grafischen Oberflächen oft markiert, gruppiert oder getrennt werden. Nach Sichtung des zu verarbeitenden Bilddatensatzes fällt auf, dass manche Screenshots durch das Selektieren mit der Maus sehr eng abgeschnitten wurden. Das ist bei dem Preprocessing ebenfalls zu berücksichtigen. Eine beispielhafte Auswahl typischer Screenshots findet sich in \autoref{annahmen_bild_eigenschaften_beispiel}.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{minipage}{0.66\textwidth}
|
||||
\includegraphics[width=\textwidth]{include/screenshots/driver_brpvi_offlineimport_004.png}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.3\textwidth}
|
||||
\begin{minipage}{\textwidth}
|
||||
\includegraphics[width=\textwidth]{include/screenshots/historian_assistent_001.png}
|
||||
\end{minipage}\hfill
|
||||
\vfill
|
||||
\begin{minipage}{\textwidth}
|
||||
\includegraphics[width=\textwidth]{include/screenshots/driver_archdrv_variablendefinition_001.png}
|
||||
\end{minipage}\hfill
|
||||
\end{minipage}
|
||||
\caption{Beispielhafte Auswahl typischer Dialogscreenshots.}
|
||||
\label{annahmen_bild_eigenschaften_beispiel}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Optimieren von Daten für Tesseract}
|
||||
\label{annahmen_bild_optimal}
|
||||
|
||||
Für die Verwendung von Tesseract ist es wichtig, unabhängig von der Diversität der Ausgangsdaten möglichst einheitliche Bilder zu erzeugen \mcite{tessdoc}. Während störende Elemente wie Bildrauschen aus dem Bild entfernt werden, sollen Texte ohne Einfluss der eigentlichen Hinter- bzw. Vordergrundfarbe gut zu erkennen sein. Auch eine deutliche Abgrenzung von Formen oder grafischen Symbolen ist von großer Wichtigkeit \mcite{sporici2020improving} \mcite{mursari2021effectiveness}. Wie in \autoref{fig:screenshot_comparison_optimal} gezeigt, sollen farbige Hintergrundflächen und grafische Dekorationselemente verschwinden. Übrig bleibt optimalerweise nur der gut lesbare textuelle Inhalt des Bildes.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=0.45\textwidth]{include/screenshots/command-processing_screentypes_controlgroup_005.png}}
|
||||
\hfill
|
||||
\fbox{\includegraphics[width=0.45\textwidth]{\detokenize{include/results/ThresholdProcessor(40\%).00.command-processing_screentypes_controlgroup_005.png}}}
|
||||
\caption{Ein optimales Ergebnisbild. Jegliche farblichen Flächen wurden durch die Bildverarbeitung entfernt. Übrig bleibt klar lesbarer Text mit einem hohen Kontrast zum Hintergrund.}
|
||||
\label{fig:screenshot_comparison_optimal}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Nachbearbeitung}
|
||||
\label{annahmen_postprocessing}
|
||||
|
||||
\subsubsection{Filtern von Symbolen}
|
||||
|
||||
Bei der Texterkennung kann es vorkommen, dass grafische Elemente als diverse Unicode-Symbole erkannt werden. Wie in \autoref{fig:screenshot_postprocessing}, wird oftmals versucht, grafische Dekorationselemente textuell nachzubilden. Auch finden sich in den ungefilterten Ergebnisdaten oft Aufzählungszeichen wie "•" oder unterschiedliche Varianten von Bindestrichen "‒". Diese Zeichen sind gemäß Anwendungsanforderungen nicht relevant für die Schlagwortsuche und können somit entfernt \bzw ignoriert werden.
|
||||
|
||||
\begin{figure}[t]
|
||||
\centering
|
||||
\begin{minipage}{0.45\textwidth}
|
||||
\includegraphics[width=0.90\textwidth]{include/postprocessing/source.png}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\lstinputlisting[firstnumber=100,linerange={100-110}]{include/postprocessing/source.json}
|
||||
\end{minipage}
|
||||
\caption{Auszug aus den ungefilterten Ergebnisdaten bei Durchführung der Texterkennung in dem gezeigten Screenshot.}
|
||||
\label{fig:screenshot_postprocessing}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Mehrsprachigkeit}
|
||||
\label{annahmen_mehrsprachigkeit}
|
||||
|
||||
Das Textverarbeitungssystem muss in der Lage sein, mehrsprachige Bilddateien einlesen und interpretieren zu können. So sollen beispielsweise Bilder mit englischen, deutschen oder italienischen Inhalten zugeführt und die Ergebnisdaten richtig verarbeitet werden können. Um eine Filterung für verschiedene Zeichensätze zu ermöglichen und eine Unterstützung für Sprachen mit nicht-lateinischen Schriften zu gewährleisten, werden dynamische Sprachfilter verwendet, die individuell an die jeweilige Sprache angepasst werden können. Für die weitere Beschreibung der generellen Vorgehensweise und Tests werden in den folgenden Schritten jedoch nur deutsche oder englische Inhalte verwendet.
|
||||
|
||||
\subsubsection{Schlagworte}
|
||||
\label{annahmen_schlagworte}
|
||||
|
||||
Für die spätere Suche von Screenshots sollen relevante Schlagworte aus den erkannten Textdaten extrahiert werden. Ein Wort eignet sich dann als Schlagwort, wenn es in relevantem Bezug zum jeweiligen Bild steht und dabei eine wichtige Aktion oder Information widerspiegelt. Inhalte, die direkt in der grafischen Benutzeroberfläche ersichtlich sind, haben daher einen hohen Informationsgehalt und eignen sich besonders gut als Suchworte. Um die Schlagwortmenge so aussagekräftig wie möglich zu halten, müssen Wörter mit geringer Bedeutung entfernt werden. Beispielsweise haben sogenannte Stoppwörter (\engl{Stop words}) wie \textit{und} oder \textit{oder} keine besondere Semantik und fördern aufgrund ihrer Häufigkeit das Auftreten von Verwechslungen \mcite{wilbur1992automatic}.
|
||||
@@ -1,6 +1,8 @@
|
||||
\chapter{Konzept}
|
||||
\label{konzept}
|
||||
|
||||
\input{chapters/c30_konzept/annahmen}
|
||||
\input{chapters/c30_konzept/vergleich/index}
|
||||
\input{chapters/c30_konzept/algorithmen/index}
|
||||
Im folgenden Kapitel wird eine Auswahl an verwendeten \hyperref[konzept_texterkennungssystem]{Technologien} und \hyperref[algorithmen_preprocessing]{Algorithmen} getroffen. Auch wird der Grundstein für den \hyperref[konzept_testaufbau]{Testaufbau} gelegt, anhand dessen später die prototypische Implementierung erfolgt.
|
||||
|
||||
\input{chapters/c30_konzept/technologien}
|
||||
\input{chapters/c30_konzept/algorithmen/index}
|
||||
\input{chapters/c30_konzept/testaufbau}
|
||||
9
chapters/c30_konzept/technologien.tex
Normal file
9
chapters/c30_konzept/technologien.tex
Normal file
@@ -0,0 +1,9 @@
|
||||
\section{Texterkennungssystem}
|
||||
\label{konzept_texterkennungssystem}
|
||||
|
||||
Wie bereits in \autoref{texerkennungssysteme} beschrieben, ist die Nutzung vieler OCR-Anwendungen \bzw Dienstleistungen kostenpflichtig und die genaue innere Vorgehensweise dieser Programme ist nicht öffentlich bekannt \mcite{textract_pricing, gcv_pricing, azurevision_pricing}. Aufgrund dieser Tatsachen ist die Wahl des Texterkennungssystems für die prototypische Implementierung dieser Bachelorarbeit auf die quelloffene und kostenlose Tesseract Open Source OCR Engine gefallen.
|
||||
|
||||
\section{Bildbearbeitungswerkzeug}
|
||||
\label{konzept_bildbearbeitungswerkzeug}
|
||||
|
||||
Als Werkzeug für die Durchführung der notwendigen Bildbearbeitungsschritte wurde aufgrund persönlicher Erfahrungen die Softwarebibliothek "ImageMagick" \mcite{imagemagick} gewählt. Sie ist umfassend dokumentiert, flexibel und kann Dank der Unterstützung für eine Vielzahl von Programmiersprachen direkt in Programme eingebunden werden. Viele in der Bildverarbeitung genutzte Operationen sind bereits implementiert, was schnelles Prototyping vereinfacht. Dadurch ist die Bibliothek eine ideale Wahl für die Realisierung von Bildbearbeitungsschritten in der prototypischen Implementierung, sie kann jedoch auch durch eine andere Implementierung ersetzt werden.
|
||||
6
chapters/c30_konzept/testaufbau.tex
Normal file
6
chapters/c30_konzept/testaufbau.tex
Normal file
@@ -0,0 +1,6 @@
|
||||
\section{Testaufbau}
|
||||
\label{konzept_testaufbau}
|
||||
|
||||
Der Testaufbau soll ein dynamisches Verketten von unterschiedlichen Bildverarbeitungs- und Textfilterungsschritten erlauben.
|
||||
|
||||
Für einen objektiven Vergleich zwischen den verschiedenen Vorgehensweisen und Algorithmen wird eine Grundabfolge der jeweiligen Schritte in einer "Processing-Pipeline" definiert. Diese Grundabfolge kann anschließend mit den jeweiligen zu vergleichenden Algorithmen erweitert werden. Die Ergebnisse können schließlich anhand der in \autoref{metriken} beschriebenen Fehlermetriken mit einer durch den Menschen verschlagworteten Vergleichsmenge abgeglichen werden.
|
||||
@@ -1,5 +0,0 @@
|
||||
\section{Vergleich}
|
||||
\label{vergleich}
|
||||
|
||||
\input{chapters/c30_konzept/vergleich/metriken}
|
||||
\input{chapters/c30_konzept/vergleich/testaufbau}
|
||||
@@ -1,4 +0,0 @@
|
||||
\subsection{Testaufbau}
|
||||
\label{testaufbau}
|
||||
|
||||
Der Testaufbau im Rahmen der Implementierung, beschrieben in \autoref{implementierung}, erlaubt ein dynamisches Verketten von unterschiedlichen Bildverarbeitungs- und Textfilterungsschritten. Für einen objektiven Vergleich zwischen den verschiedenen Vorgehensweisen und Algorithmen wird eine Grundabfolge der jeweiligen Schritte in einer "Processing-Pipeline" definiert. Die Ergebnisse können schließlich anhand der in \autoref{metriken} beschriebenen Fehlermetriken mit einer durch den Menschen verschlagworteten Vergleichsmenge abgeglichen werden.
|
||||
@@ -1,353 +0,0 @@
|
||||
\section{Implementierung}
|
||||
\label{implementierung}
|
||||
|
||||
\subsection{Vergleichsdaten}
|
||||
|
||||
Als Ausgangsdaten für die Durchführung wurde eine zufällige Auswahl an Dokumentationsscreenshots, wie in \autoref{fig:screenshot_beispiel_gut} abgebildet, getroffen. Zusätzlich wurden auch Bilder wie in \autoref{fig:screenshot_beispiel_schlecht} in die Stichprobe mit aufgenommen, die beispielsweise aufgrund ihrer Auflösung oder Kontrastverhältnisse schwer lesbar sind.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=.7\textwidth]{include/screenshots/driver_SEL_Options_002.png}}
|
||||
\caption{Ein gut für die Texterkennung geeigneter Screenshot. Die wesentlichen Inhalte weisen einen guten Kontrast zum Hintergrund auf und befinden sich in Bereichen mit gleichmäßiger Helligkeit.}
|
||||
\label{fig:screenshot_beispiel_gut}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=.7\textwidth]{include/screenshots/editor_startpage_project-exist_001.png}}
|
||||
\caption{Ein schlecht lesbarer Screenshot. Aufgrund der vielen Symbole und der bunten Flächen stellt dieses Bild eine Herausforderung für das Texterkennungssystem dar.}
|
||||
\label{fig:screenshot_beispiel_schlecht}
|
||||
\end{figure}
|
||||
|
||||
Die textuellen Inhalte aller ausgewählten Bilder wurden anschließend manuell extrahiert und für den programmatischen Vergleich in einer Datei im selben Verzeichnis wie die Quellbilddatei festgehalten. Ein Beispiel dafür ist der Screenshot "zrs\_ZAMS\_filter-alarmgroup\_001" in \autoref{fig:screenshot_verschlagwortet}, welcher insgesamt 15 verschiedene Wörter beinhaltet.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\includegraphics[width=0.99\textwidth]{include/screenshots/zrs_ZAMS_filter-alarmgroup_001.png}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.45\textwidth}
|
||||
\lstinputlisting[numbers=none]{include/screenshots/zrs_ZAMS_filter-alarmgroup_001.json}
|
||||
\end{minipage}
|
||||
\caption{Ein Screenshot und die daraus manuell extrahierten Schlagworte.}
|
||||
\label{fig:screenshot_verschlagwortet}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Verwendete Bibliotheken}
|
||||
\label{components}
|
||||
|
||||
Die für die prototypische Implementierung verwendeten Bibliotheken stellen Komponenten zur Verarbeitung von Screenshotdaten zur Verfügung. Um die Funktionalität flexibel auf unterschiedliche Anforderungen anpassen zu können, sind die Komponenten möglichst lose miteinander gekoppelt. Ein beispielhafter Ablauf eines Texterkennungsprogramms unter Nutzung der Bibliotheken ist in \autoref{fig:overview_diagram} abgebildet.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{include/flowcharts/flow_overview.png}
|
||||
\caption{Beispielhafter Ablauf eines Texterkennungsprogramms}
|
||||
\label{fig:overview_diagram}
|
||||
\end{figure}
|
||||
|
||||
\subsubsection{Fremdbibliotheken}
|
||||
\label{components_external}
|
||||
|
||||
In der prototypischen Implementierung, entwickelt in \csharp .NET, wurden in Referenz an die in \autoref{technologien} vorgestellten Technologien und Werkzeuge folgende NuGet-Bibliotheken als Basis für die Implementierung verwendet.
|
||||
|
||||
\begin{itemize}
|
||||
\item\textbf{Magick.NET} \mcite{nuget_magicknet}\\Version: 13.1.0\\Lizenz: Apache-2.0\\
|
||||
\item\textbf{Tesseract} \mcite{nuget_tesseract}\\Version: 5.2.0\\Lizenz: Apache-2.0\\
|
||||
\end{itemize}
|
||||
|
||||
\subsubsection{Verarbeitungsketten}
|
||||
\label{components_processorchain}
|
||||
|
||||
Beim Entwurf des Verarbeitungssystems für die unterschiedlichen Bild- und Textverarbeitungsschritte wurde bewusst auf Flexibilität geachtet. Mithilfe von Interfaces und Builder-Methoden ist es möglich, Verarbeitungsschritte gemäß Programm \ref{prg:processor_interface} als Prozessoren (\engl{Processors}) zu definieren. So stellt beispielsweise das Normalisieren eines durch Tesseract erkannten Wortes einen Verarbeitungsschritt dar, wie in Programm \ref{prg:processor_implementation} gezeigt.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface IProcessor
|
||||
{
|
||||
IEnumerable Process(IEnumerable inputs);
|
||||
}
|
||||
|
||||
public interface IProcessor<in TInput, out TOutput> : IProcessor
|
||||
{
|
||||
IEnumerable<TOutput> Process(IEnumerable<TInput> inputs);
|
||||
|
||||
new IEnumerable Process(IEnumerable inputs)
|
||||
{
|
||||
return Process((IEnumerable<TInput>)inputs);
|
||||
}
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "IProcessor.cs": Schnittstelle eines Prozessors.}
|
||||
\label{prg:processor_interface}
|
||||
\end{program}
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public class ToLowerProcessor
|
||||
: Processor<ScanResult, ScanResult>
|
||||
{
|
||||
public override IEnumerable<ScanResult> Process(
|
||||
IEnumerable<ScanResult> inputs
|
||||
)
|
||||
{
|
||||
foreach (var kv in inputs)
|
||||
{
|
||||
kv.Word.Text = kv.Word.Text.ToLower();
|
||||
yield return kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "ToLowerProcessor.cs": Normalisieren als einzelner Verarbeitungsschritt.}
|
||||
\label{prg:processor_implementation}
|
||||
\end{program}
|
||||
|
||||
Sollen mehrere Schritte verbunden werden, bietet das Processing-Framework die Möglichkeit, eine Verarbeitungskette aufzubauen. Gemäß der Schnittstellendefinition in Programm \ref{prg:processor_chain_interface} können Delegates oder komplette Prozessoren dynamisch als einzelne Schritte aneinandergereiht werden. Die Typensicherheit wird durch das generische Typensystem von \csharp stets gewahrt.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface IProcessorChainConfiguration<TInput, TOutput>
|
||||
: IProcessorChain<TInput, TOutput>
|
||||
{
|
||||
IProcessorChainConfiguration<T, TOutput, TInput, TOutput> Use<T>(
|
||||
IProcessor<TInput, T> processor);
|
||||
|
||||
IProcessorChainConfiguration<T, TOutput, TInput, TOutput> Use<T>(
|
||||
Func<IEnumerable<TInput>, IEnumerable<T>> processorFunc);
|
||||
|
||||
IProcessorChainConfiguration<TInput, TOutput> Complete(
|
||||
IProcessor<TInput, TOutput> processor);
|
||||
|
||||
IProcessorChainConfiguration<TInput, TOutput> Complete(
|
||||
Func<IEnumerable<TInput>, IEnumerable<TOutput>> processorFunc);
|
||||
}
|
||||
|
||||
public interface IProcessorChainConfiguration<TInput, TOutput, TInChain, TOutChain>
|
||||
{
|
||||
IProcessorChainConfiguration<T, TOutput, TInChain, TOutChain> Use<T>(
|
||||
IProcessor<TInput, T> processor);
|
||||
|
||||
IProcessorChainConfiguration<T, TOutput, TInChain, TOutChain> Use<T>(
|
||||
Func<IEnumerable<TInput>, IEnumerable<T>> processorFunc);
|
||||
|
||||
IProcessorChain<TInChain, TOutChain> Complete(
|
||||
IProcessor<TInput, TOutput> processor);
|
||||
|
||||
IProcessorChain<TInChain, TOutChain> Complete(
|
||||
Func<IEnumerable<TInput>, IEnumerable<TOutput>> processorFunc);
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "IProcessorChainConfiguration.cs": Schnittstelle zur Konfiguration einer Verarbeitungskette}
|
||||
\label{prg:processor_chain_interface}
|
||||
\end{program}
|
||||
|
||||
Ist die Aufbauphase abgeschlossen, kann die Verarbeitungskette, konfiguriert in Programm \ref{prg:processor_chain_implementation}, gestartet werden.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
var postProcessor = new ProcessorChainConfiguration<ScanResult, ScanResult>()
|
||||
.Use(new ConfidenceFilter(50))
|
||||
.Use(new ToLowerProcessor())
|
||||
.Use(new DuplicateFilter())
|
||||
.Complete(new RegexFilter(WordRegex));
|
||||
|
||||
// ...
|
||||
|
||||
postProcessor.Process(data);
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "ImageViewModel.cs": Konfiguration und Starten einer Verarbeitungskette.}
|
||||
\label{prg:processor_chain_implementation}
|
||||
\end{program}
|
||||
|
||||
Abhängig von den verwendeten Prozessoren können also Eingangsdaten jeglichen Typs, in diesem Fall Bildobjekte der Magick.NET Bibliothek oder Ergebnisdaten des Texterkennungsvorgangs dynamisch verarbeitet werden.
|
||||
|
||||
\subsubsubsection{Bildverarbeitungskette}
|
||||
\label{processor_chain_image}
|
||||
|
||||
Für den Ablauf der Bildverarbeitung und der anschließenden Ergebnisfilterung werden die Erkenntnisse aus \autoref{konzept} mithilfe des in \autoref{components_processorchain} beschriebenen Processing-Frameworks angewandt. Die resultierende Konfiguration folgt dem Ablauf aus \autoref{fig:preprocessor_diagram} und \autoref{fig:postprocessor_diagram} und ist in Programm \ref{prg:preprocessor_definition} \bzw \ref{prg:postprocessor_definition} definiert.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{include/flowcharts/flow_preprocessing.png}
|
||||
\caption{Beispielhafter Ablauf der Vorverarbeitungskette}
|
||||
\label{fig:preprocessor_diagram}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{include/flowcharts/flow_postprocessing.png}
|
||||
\caption{Beispielhafter Ablauf der Nachbearbeitungskette}
|
||||
\label{fig:postprocessor_diagram}
|
||||
\end{figure}
|
||||
|
||||
Angefangen mit einem Ausgangsbild, welches über die Softwarebibliothek Magick.NET geladen wurde, beginnt die Bildverarbeitung zunächst mit dem Resampling. Falls der geladene Screenshot die Mindestauflösung von 300 dpi unterschreitet, wird es mittels Lanczos2-Verfahren, eine von Magick.NET mitgelieferte Implementierung des Lanczos2-Algorithmus mit leichter Schärfung \mcite{imagemagick}, auf die Mindestauflösung vergrößert. Anschließend wird das Bild normalisiert, in Graustufen umgewandelt und jegliche Transparenz durch einen weißen Hintergrund ersetzt. Danach wird es mittels Schwellwertverfahren binarisiert. Rund um das Bild wird ein Rahmen mit einer Dicke von 10px eingefügt. Um Texterkennungsfehler durch falsche Vorder- \bzw Hintergrundfarben auszuschließen, wird das Bild gemeinsam mit einer farblich invertierten Version an das Texterkennungssystem weitergegeben.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
var preprocessing = new ProcessorChainConfiguration<MagickImage, MagickImage>()
|
||||
.Use(new CloneImageProcessor())
|
||||
.Use(new ResizeProcessor(FilterType.Lanczos2Sharp, PixelInterpolateMethod.Mesh))
|
||||
.Use(new NormalizeProcessor())
|
||||
.Use(_thresholdProcessor)
|
||||
.Use(new AddBorderProcessor(10))
|
||||
.Use(new BinarizeProcessor())
|
||||
.Use(new NegateCloneProcessor())
|
||||
.Complete(OnPreprocessed);
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "EvaluationProcessor.cs": Definition der Preprocessing-Kette.}
|
||||
\label{prg:preprocessor_definition}
|
||||
\end{program}
|
||||
|
||||
Wurde der übergebene Screenshot vom Texterkennungssystem verarbeitet, müssen nun die Ergebnisse gefiltert werden. Dazu werden zunächst die Metadaten der einzelnen Wörter betrachtet und alle Elemente mit einer Confidence unter einem Schwellenwert von 50\% verworfen. Danach werden die erkannten Texte mittels der \csharp-Funktion \lstinline{ToLower()} normalisiert und anschließend auf Duplikate untersucht. Wurden alle Duplikate verworfen, werden die Wörter mittels sprachabhängigen Regular Expressions untersucht. Gemäß den Annahmen in \autoref{annahmen_mehrsprachigkeit} wurde ein simpler englischer (\lstinline|[\w'\-]{2,}|) sowie deutscher (\lstinline|[\w'\-äöüÄÖÜß]{2,}|) Sprachfilter festgelegt.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
var postprocessing = new ProcessorChainConfiguration<ScanResult, ScanResult>()
|
||||
.Use(new ConfidenceFilter(50))
|
||||
.Use(new ToLowerProcessor())
|
||||
.Use(new DuplicateFilter())
|
||||
.Complete(new RegexFilter(wordRegex));
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "EvaluationProcessor.cs": Definition der Postprocessing-Kette.}
|
||||
\label{prg:postprocessor_definition}
|
||||
\end{program}
|
||||
|
||||
\subsubsection{Lookup}
|
||||
|
||||
Die "Lookup" Bibliothek abstrahiert das Speichern von Schlüssel-Wert-Paaren. Dabei kann flexibel zwischen verschiedenen Speicherimplementierungen gewechselt werden. So ist es beispielsweise möglich, die Werte in einer Listenstruktur im Arbeitsspeicher, in einer Datei oder -- mittels der EntityFramework-Bibliothek, welche von der .NET Foundation entwickelt wird -- in einer Datenbank persistent abzulegen. Unabhängig von der Ablagestruktur im Hintergrund können Lookups mittels einer gemeinsamen Schnittstelle, abgebildert in Programm \ref{prg:lookup_interface}, manipuliert werden.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface ILookup<TKey, TValue>
|
||||
: ILookup,
|
||||
IDictionary<TKey, ICollection<TValue>>,
|
||||
IDisposable
|
||||
{
|
||||
ICollection<TValue> Add(TKey key);
|
||||
|
||||
public void Add(TKey key, TValue value);
|
||||
|
||||
public void AddRange(TKey key, IEnumerable<TValue> values);
|
||||
|
||||
public bool Remove(TKey key, TValue value);
|
||||
|
||||
public ICollection<TValue> GetOrAdd(TKey key);
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "ILookup.cs": Definition der gemeinsamen Schnittstelle für Lookups}
|
||||
\label{prg:lookup_interface}
|
||||
\end{program}
|
||||
|
||||
\subsubsection{Optische Texterkennung}
|
||||
|
||||
Die OCR-Bibliothek beinhaltet elementare Funktionen für die Texterkennung. Sie enthält Funktionen zur Bearbeitung von Bildern mittels Magick.NET inklusive anschließender Verarbeitung mittels Tesseract. Kernkomponenten wie das Texterkennungssystem werden automatisch auf Basis der Eingabeparameter konfiguriert und die Verwendung der Ergebnisdaten in externen Programmteilen wird durch die Zurverfügungstellung von Datenmodellen für die Ergebnisdaten vereinfacht. Außerdem enthält die Bibliothek eine Reihe von vordefinierten Verarbeitungsketten \bzw Prozessoren für die Bild- und Textverarbeitung.
|
||||
|
||||
\subsubsection{Automatische Berichterstellung}
|
||||
\label{components_reportgenerator}
|
||||
|
||||
Mithilfe des ReportGenerator-Frameworks wird die automatische Berichterstellung für unterschiedlichste Ausgabeformate abstrahiert. Durch die mitgelieferten Schnittstellendefinitionen ist es möglich, eigene Ausgabeformate zu definieren. Der gesamte Funktionsumfang des ReportGenerators, beispielsweise das Erstellen von Tabellen oder das Anlegen und Überschriften, kann durch die Implementierung von Interfaces wie Programm \ref{prg:reportgenerator_interface} an die jeweilige Syntax und Dokumentstruktur angepasst werden.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface IDocumentGenerator : IStreamWriter
|
||||
{
|
||||
IDocumentGenerator Append(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendLine(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendParagraph(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendHeading(int level, string text);
|
||||
|
||||
IDocumentGenerator AppendTable(int columns, Action<ITableGenerator> table);
|
||||
|
||||
string FormatImage(string path, IBounds? bounds = default);
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "IDocumentGenerator.cs": Hauptschnittstelle für den ReportGenerator}
|
||||
\label{prg:reportgenerator_interface}
|
||||
\end{program}
|
||||
|
||||
\subsection{Programmablauf}
|
||||
|
||||
Die prototypische Implementierung besteht neben den oben genannten Komponenten aus einem ausführbaren Kommandozeilenprogramm zur Texterkennung und einem Programm zum Vergleich der Ergebnisse mit den manuell verschlagworteten Soll-Daten. Alle relevanten Daten werden in entsprechenden Ausgabeverzeichnissen festgehalten und dadurch für den jeweiligen nächsten Schritt verfügbar gemacht.
|
||||
|
||||
\subsubsection{Texterkennung}
|
||||
|
||||
Zu Beginn der Ausführung des Kommandozeilenprogramms wird für jedes zu verarbeitende Bild abhängig von den definierten Schwellenwertverfahren eine Reihe von Prozessoren angelegt. Dazu wurde der statische Teil der Bildverarbeitungskette gemäß \autoref{processor_chain_image} innerhalb der "EvaluationProcessor" Klasse definiert, wie in Programm \ref{prg:processor_definition_dynamic} auszugsweise dargestellt. Lediglich die zu evaluierenden Prozessoren für die jeweiligen Schwellwertverfahren können außerhalb der Klasse dynamisch definiert werden. Der EvaluationProcessor legt die erzeugten Ergebnisdaten, bestehend aus den gefundenen Wörtern und zugehörigen Metadaten wie die Confidence, auf Dateiebene ab. Um überprüfen zu können, welches Bild schlussendlich an das Texterkennungssystem übergeben wurde, werden auch die verarbeiteten Bilder nach der Binarisierung gespeichert.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
private static IEnumerable<EvaluationProcessor> MakeThresholdVariations()
|
||||
{
|
||||
for (int i = 4; i <= 24; i += 4)
|
||||
{
|
||||
yield return new(new ThresholdAdaptiveProcessor(i));
|
||||
}
|
||||
|
||||
for (int i = 20; i <= 80; i += 10)
|
||||
{
|
||||
yield return new(new ThresholdProcessor(i));
|
||||
}
|
||||
|
||||
yield return new(new AutoThresholdProcessor(AutoThresholdMethod.Kapur));
|
||||
yield return new(new AutoThresholdProcessor(AutoThresholdMethod.OTSU));
|
||||
yield return new(new AutoThresholdProcessor(AutoThresholdMethod.Triangle));
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "Program.cs": Definition der Thresholding Prozessoren.}
|
||||
\label{prg:processor_definition_dynamic}
|
||||
\end{program}
|
||||
|
||||
Ist die Erstellung der Bildbearbeitungsprozessoren abgeschlossen, wird jeder einzelne Prozessor über die Systembibliothek "System.Threading.Tasks" als eigene Ausführungseinheit (\engl{Task}) gestartet. In der Kommandozeile wird anschließend der aktuelle Status jedes Tasks angezeigt. Wurden alle Tasks abgeschlossen, wird das Programm beendet.
|
||||
|
||||
\subsubsection{Vergleich mit Soll-Daten}
|
||||
|
||||
Wurden die in den jeweiligen Screenshots erkannten Textdaten abgelegt, werden diese Daten im zweiten Kommandozeilenprogramm "ReportGenerator" nun mit den manuell verschlagworteten Daten verglichen und die Ergebnisse in einen Bericht (\engl{Report}) gespeichert.
|
||||
|
||||
Als zentrale Komponente für den Vergleich spielt die Berechnung der in \autoref{metriken} erklärten Metriken eine wesentliche Rolle. Wie in Programm \ref{prg:distance_levenshtein} ersichtlich, wird die Distanz zwischen zwei \csharp-Enumerables, seien es zwei Strings oder zwei Listen, über das Verfahren nach Levenshtein berechnet.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public static double GetDistance<T>(T reference, T? hypothesis)
|
||||
where T : IEnumerable
|
||||
{
|
||||
var refArr = reference.Cast<object>().ToArray();
|
||||
var hypArr = hypothesis?.Cast<object>().ToArray() ?? Array.Empty<object>();
|
||||
|
||||
var distance = new int[refArr.Length + 1, hypArr.Length + 1];
|
||||
|
||||
for (var x = 0; x <= refArr.Length; x++)
|
||||
{
|
||||
distance[x, 0] = x;
|
||||
}
|
||||
|
||||
for (var y = 0; y <= hypArr.Length; y++)
|
||||
{
|
||||
distance[0, y] = y;
|
||||
}
|
||||
|
||||
for (var x = 0; x < refArr.Length; x++)
|
||||
{
|
||||
for (var y = 0; y < hypArr.Length; y++)
|
||||
{
|
||||
var cost = Equals(refArr[x], hypArr[y]) ? 0 : 1;
|
||||
|
||||
var c1 = distance[x, y] + cost; // Bottom left
|
||||
|
||||
var c2 = distance[x, y + 1] + 1; // Top left
|
||||
var c3 = distance[x + 1, y] + 1; // Bottom right
|
||||
|
||||
distance[x + 1, y + 1] = Min(c1, c2, c3); // Top right
|
||||
}
|
||||
}
|
||||
|
||||
return distance[refArr.Length, hypArr.Length];
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "Calculator.cs": Berechnung der Levenshtein-Distanz.}
|
||||
\label{prg:distance_levenshtein}
|
||||
\end{program}
|
||||
|
||||
Nach der Ermittlung der jeweiligen Distanzen auf Wort- \bzw Bildbasis werden sie mit den jeweiligen Ursprungsbildern, Prozessoren und den verwendeten Algorithmen in Bezug gesetzt. Die so aufbereiteten Ergebnisse werden anschließend an den ReportGenerator übergeben und in einen Bericht zusammengefasst.
|
||||
@@ -1,5 +1,355 @@
|
||||
\chapter{Implementierung}
|
||||
\label{durchführung}
|
||||
\label{implementierung}
|
||||
|
||||
\input{chapters/c40_durchführung/implementierung}
|
||||
\input{chapters/c40_durchführung/analyse}
|
||||
In der prototypischen Implementierung werden die in \autoref{grundlagen} \bzw \autoref{konzept} angeführten Algorithmen zu Verarbeitungsketten zusammengefügt. Anhand einer Stichprobe wird anschließend ein automatisierter Bericht generiert, welche detaillierte Informationen über Gesamtergebnisse der Texterkennung mit den jeweiligen Bildern und den verwendeten Algorithmen in Bezug setzt.
|
||||
|
||||
\section{Komponenten und Bibliotheken}
|
||||
\label{components}
|
||||
|
||||
Die für die prototypische Implementierung verwendeten Bibliotheken stellen Komponenten zur Verarbeitung von Screenshotdaten zur Verfügung. Um die Funktionalität flexibel auf unterschiedliche Anforderungen anpassen zu können, sind die Komponenten möglichst lose miteinander gekoppelt. Ein beispielhafter Ablauf eines Texterkennungsprogramms unter Nutzung der Bibliotheken ist in \autoref{fig:overview_diagram} abgebildet.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{include/flowcharts/flow_overview.png}
|
||||
\caption{Beispielhafter Ablauf eines Texterkennungsprogramms}
|
||||
\label{fig:overview_diagram}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Fremdbibliotheken}
|
||||
\label{components_external}
|
||||
|
||||
In der prototypischen Implementierung, entwickelt in \csharp .NET, wurden in Referenz an die in \autoref{technologien} vorgestellten Technologien und Werkzeuge folgende NuGet-Bibliotheken als Basis für die Implementierung verwendet.
|
||||
|
||||
\begin{itemize}
|
||||
\item\textbf{Magick.NET} \mcite{nuget_magicknet}\\Version: 13.1.0\\Lizenz: Apache-2.0\\
|
||||
\item\textbf{Tesseract} \mcite{nuget_tesseract}\\Version: 5.2.0\\Lizenz: Apache-2.0\\
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Verarbeitungsketten}
|
||||
\label{components_processorchain}
|
||||
|
||||
Beim Entwurf des Verarbeitungssystems für die unterschiedlichen Bild- und Textverarbeitungsschritte wurde bewusst auf Flexibilität geachtet. Mithilfe von Interfaces und Builder-Methoden ist es möglich, Verarbeitungsschritte gemäß Programm \ref{prg:processor_interface} als Prozessoren (\engl{Processors}) zu definieren. So stellt beispielsweise das Normalisieren eines durch Tesseract erkannten Wortes einen Verarbeitungsschritt dar, wie in Programm \ref{prg:processor_implementation} gezeigt.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface IProcessor
|
||||
{
|
||||
IEnumerable Process(IEnumerable inputs);
|
||||
}
|
||||
|
||||
public interface IProcessor<in TInput, out TOutput> : IProcessor
|
||||
{
|
||||
IEnumerable<TOutput> Process(IEnumerable<TInput> inputs);
|
||||
|
||||
new IEnumerable Process(IEnumerable inputs)
|
||||
{
|
||||
return Process((IEnumerable<TInput>)inputs);
|
||||
}
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "IProcessor.cs": Schnittstelle eines Prozessors.}
|
||||
\label{prg:processor_interface}
|
||||
\end{program}
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public class ToLowerProcessor
|
||||
: Processor<ScanResult, ScanResult>
|
||||
{
|
||||
public override IEnumerable<ScanResult> Process(
|
||||
IEnumerable<ScanResult> inputs
|
||||
)
|
||||
{
|
||||
foreach (var kv in inputs)
|
||||
{
|
||||
kv.Word.Text = kv.Word.Text.ToLower();
|
||||
yield return kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "ToLowerProcessor.cs": Normalisieren als einzelner Verarbeitungsschritt.}
|
||||
\label{prg:processor_implementation}
|
||||
\end{program}
|
||||
|
||||
Sollen mehrere Schritte verbunden werden, bietet das Processing-Framework die Möglichkeit, eine Verarbeitungskette aufzubauen. Gemäß der Schnittstellendefinition in Programm \ref{prg:processor_chain_interface} können Delegates oder komplette Prozessoren dynamisch als einzelne Schritte aneinandergereiht werden. Die Typensicherheit wird durch das generische Typensystem von \csharp stets gewahrt.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface IProcessorChainConfiguration<TInput, TOutput>
|
||||
: IProcessorChain<TInput, TOutput>
|
||||
{
|
||||
IProcessorChainConfiguration<T, TOutput, TInput, TOutput> Use<T>(
|
||||
IProcessor<TInput, T> processor);
|
||||
|
||||
IProcessorChainConfiguration<T, TOutput, TInput, TOutput> Use<T>(
|
||||
Func<IEnumerable<TInput>, IEnumerable<T>> processorFunc);
|
||||
|
||||
IProcessorChainConfiguration<TInput, TOutput> Complete(
|
||||
IProcessor<TInput, TOutput> processor);
|
||||
|
||||
IProcessorChainConfiguration<TInput, TOutput> Complete(
|
||||
Func<IEnumerable<TInput>, IEnumerable<TOutput>> processorFunc);
|
||||
}
|
||||
|
||||
public interface IProcessorChainConfiguration<TInput, TOutput, TInChain, TOutChain>
|
||||
{
|
||||
IProcessorChainConfiguration<T, TOutput, TInChain, TOutChain> Use<T>(
|
||||
IProcessor<TInput, T> processor);
|
||||
|
||||
IProcessorChainConfiguration<T, TOutput, TInChain, TOutChain> Use<T>(
|
||||
Func<IEnumerable<TInput>, IEnumerable<T>> processorFunc);
|
||||
|
||||
IProcessorChain<TInChain, TOutChain> Complete(
|
||||
IProcessor<TInput, TOutput> processor);
|
||||
|
||||
IProcessorChain<TInChain, TOutChain> Complete(
|
||||
Func<IEnumerable<TInput>, IEnumerable<TOutput>> processorFunc);
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "IProcessorChainConfiguration.cs": Schnittstelle zur Konfiguration einer Verarbeitungskette}
|
||||
\label{prg:processor_chain_interface}
|
||||
\end{program}
|
||||
|
||||
Ist die Aufbauphase abgeschlossen, kann die Verarbeitungskette, konfiguriert in Programm \ref{prg:processor_chain_implementation}, gestartet werden.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
var postProcessor = new ProcessorChainConfiguration<ScanResult, ScanResult>()
|
||||
.Use(new ConfidenceFilter(50))
|
||||
.Use(new ToLowerProcessor())
|
||||
.Use(new DuplicateFilter())
|
||||
.Complete(new RegexFilter(WordRegex));
|
||||
|
||||
// ...
|
||||
|
||||
postProcessor.Process(data);
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "ImageViewModel.cs": Konfiguration und Starten einer Verarbeitungskette.}
|
||||
\label{prg:processor_chain_implementation}
|
||||
\end{program}
|
||||
|
||||
Abhängig von den verwendeten Prozessoren können also Eingangsdaten jeglichen Typs, in diesem Fall Bildobjekte der Magick.NET Bibliothek oder Ergebnisdaten des Texterkennungsvorgangs dynamisch verarbeitet werden.
|
||||
|
||||
\subsubsection{Bildverarbeitungskette}
|
||||
\label{processor_chain_image}
|
||||
|
||||
Für den Ablauf der Bildverarbeitung und der anschließenden Ergebnisfilterung werden die Erkenntnisse aus \autoref{konzept} mithilfe des in \autoref{components_processorchain} beschriebenen Processing-Frameworks angewandt. Die resultierende Konfiguration folgt dem Ablauf aus \autoref{fig:preprocessor_diagram} und \autoref{fig:postprocessor_diagram} und ist in Programm \ref{prg:preprocessor_definition} \bzw \ref{prg:postprocessor_definition} definiert.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{include/flowcharts/flow_preprocessing.png}
|
||||
\caption{Beispielhafter Ablauf der Vorverarbeitungskette}
|
||||
\label{fig:preprocessor_diagram}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\includegraphics[width=.9\textwidth]{include/flowcharts/flow_postprocessing.png}
|
||||
\caption{Beispielhafter Ablauf der Nachbearbeitungskette}
|
||||
\label{fig:postprocessor_diagram}
|
||||
\end{figure}
|
||||
|
||||
Angefangen mit einem Ausgangsbild, welches über die Softwarebibliothek Magick.NET geladen wurde, beginnt die Bildverarbeitung zunächst mit dem Resampling. Falls der geladene Screenshot die Mindestauflösung von 300 dpi unterschreitet, wird es mittels Lanczos2-Verfahren, eine von Magick.NET mitgelieferte Implementierung des Lanczos2-Algorithmus mit leichter Schärfung \mcite{imagemagick}, auf die Mindestauflösung vergrößert. Anschließend wird das Bild normalisiert, in Graustufen umgewandelt und jegliche Transparenz durch einen weißen Hintergrund ersetzt. Danach wird es mittels Schwellwertverfahren binarisiert. Rund um das Bild wird ein Rahmen mit einer Dicke von 10px eingefügt. Um Texterkennungsfehler durch falsche Vorder- \bzw Hintergrundfarben auszuschließen, wird das Bild gemeinsam mit einer farblich invertierten Version an das Texterkennungssystem weitergegeben.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
var preprocessing = new ProcessorChainConfiguration<MagickImage, MagickImage>()
|
||||
.Use(new CloneImageProcessor())
|
||||
.Use(new ResizeProcessor(FilterType.Lanczos2Sharp, PixelInterpolateMethod.Mesh))
|
||||
.Use(new NormalizeProcessor())
|
||||
.Use(_thresholdProcessor)
|
||||
.Use(new AddBorderProcessor(10))
|
||||
.Use(new BinarizeProcessor())
|
||||
.Use(new NegateCloneProcessor())
|
||||
.Complete(OnPreprocessed);
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "EvaluationProcessor.cs": Definition der Preprocessing-Kette.}
|
||||
\label{prg:preprocessor_definition}
|
||||
\end{program}
|
||||
|
||||
Wurde der übergebene Screenshot vom Texterkennungssystem verarbeitet, müssen nun die Ergebnisse gefiltert werden. Dazu werden zunächst die Metadaten der einzelnen Wörter betrachtet und alle Elemente mit einer Confidence unter einem Schwellenwert von 50\% verworfen. Danach werden die erkannten Texte mittels der \csharp-Funktion \lstinline{ToLower()} normalisiert und anschließend auf Duplikate untersucht. Wurden alle Duplikate verworfen, werden die Wörter mittels sprachabhängigen Regular Expressions untersucht. Gemäß den Annahmen in \autoref{annahmen_mehrsprachigkeit} wurde ein simpler englischer (\lstinline|[\w'\-]{2,}|) sowie deutscher (\lstinline|[\w'\-äöüÄÖÜß]{2,}|) Sprachfilter festgelegt.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
var postprocessing = new ProcessorChainConfiguration<ScanResult, ScanResult>()
|
||||
.Use(new ConfidenceFilter(50))
|
||||
.Use(new ToLowerProcessor())
|
||||
.Use(new DuplicateFilter())
|
||||
.Complete(new RegexFilter(wordRegex));
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "EvaluationProcessor.cs": Definition der Postprocessing-Kette.}
|
||||
\label{prg:postprocessor_definition}
|
||||
\end{program}
|
||||
|
||||
\subsection{Lookup}
|
||||
|
||||
Die "Lookup" Bibliothek abstrahiert das Speichern von Schlüssel-Wert-Paaren. Dabei kann flexibel zwischen verschiedenen Speicherimplementierungen gewechselt werden. So ist es beispielsweise möglich, die Werte in einer Listenstruktur im Arbeitsspeicher, in einer Datei oder -- mittels der EntityFramework-Bibliothek, welche von der .NET Foundation entwickelt wird -- in einer Datenbank persistent abzulegen. Unabhängig von der Ablagestruktur im Hintergrund können Lookups mittels einer gemeinsamen Schnittstelle, abgebildert in Programm \ref{prg:lookup_interface}, manipuliert werden.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface ILookup<TKey, TValue>
|
||||
: ILookup,
|
||||
IDictionary<TKey, ICollection<TValue>>,
|
||||
IDisposable
|
||||
{
|
||||
ICollection<TValue> Add(TKey key);
|
||||
|
||||
public void Add(TKey key, TValue value);
|
||||
|
||||
public void AddRange(TKey key, IEnumerable<TValue> values);
|
||||
|
||||
public bool Remove(TKey key, TValue value);
|
||||
|
||||
public ICollection<TValue> GetOrAdd(TKey key);
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "ILookup.cs": Definition der gemeinsamen Schnittstelle für Lookups}
|
||||
\label{prg:lookup_interface}
|
||||
\end{program}
|
||||
|
||||
\subsection{Optische Texterkennung}
|
||||
|
||||
Die OCR-Bibliothek beinhaltet elementare Funktionen für die Texterkennung. Sie enthält Funktionen zur Bearbeitung von Bildern mittels Magick.NET inklusive anschließender Verarbeitung mittels Tesseract. Kernkomponenten wie das Texterkennungssystem werden automatisch auf Basis der Eingabeparameter konfiguriert und die Verwendung der Ergebnisdaten in externen Programmteilen wird durch die Zurverfügungstellung von Datenmodellen für die Ergebnisdaten vereinfacht. Außerdem enthält die Bibliothek eine Reihe von vordefinierten Verarbeitungsketten \bzw Prozessoren für die Bild- und Textverarbeitung.
|
||||
|
||||
\subsection{Automatische Berichterstellung}
|
||||
\label{components_reportgenerator}
|
||||
|
||||
Mithilfe des ReportGenerator-Frameworks wird die automatische Berichterstellung für unterschiedlichste Ausgabeformate abstrahiert. Durch die mitgelieferten Schnittstellendefinitionen ist es möglich, eigene Ausgabeformate zu definieren. Der gesamte Funktionsumfang des ReportGenerators, beispielsweise das Erstellen von Tabellen oder das Anlegen und Überschriften, kann durch die Implementierung von Interfaces wie Programm \ref{prg:reportgenerator_interface} an die jeweilige Syntax und Dokumentstruktur angepasst werden.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public interface IDocumentGenerator : IStreamWriter
|
||||
{
|
||||
IDocumentGenerator Append(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendLine(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendParagraph(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendHeading(int level, string text);
|
||||
|
||||
IDocumentGenerator AppendTable(int columns, Action<ITableGenerator> table);
|
||||
|
||||
string FormatImage(string path, IBounds? bounds = default);
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "IDocumentGenerator.cs": Hauptschnittstelle für den ReportGenerator}
|
||||
\label{prg:reportgenerator_interface}
|
||||
\end{program}
|
||||
|
||||
\section{Vergleichsdaten}
|
||||
|
||||
Als Ausgangsdaten für die Durchführung wurde eine zufällige Auswahl an Dokumentationsscreenshots getroffen, wie in \autoref{fig:screenshot_beispiel_gut} abgebildet. Zusätzlich wurden auch Bilder wie in \autoref{fig:screenshot_beispiel_schlecht} in die Stichprobe mit aufgenommen, die beispielsweise aufgrund ihrer Auflösung oder Kontrastverhältnisse schwer lesbar sind.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=.7\textwidth]{include/screenshots/driver_SEL_Options_002.png}}
|
||||
\caption{Ein gut für die Texterkennung geeigneter Screenshot. Die wesentlichen Inhalte weisen einen guten Kontrast zum Hintergrund auf und befinden sich in Bereichen mit gleichmäßiger Helligkeit.}
|
||||
\label{fig:screenshot_beispiel_gut}
|
||||
\end{figure}
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\fbox{\includegraphics[width=.7\textwidth]{include/screenshots/editor_startpage_project-exist_001.png}}
|
||||
\caption{Ein schlecht lesbarer Screenshot. Aufgrund der vielen Symbole und der bunten Flächen stellt dieses Bild eine Herausforderung für das Texterkennungssystem dar.}
|
||||
\label{fig:screenshot_beispiel_schlecht}
|
||||
\end{figure}
|
||||
|
||||
Die textuellen Inhalte aller ausgewählten Bilder wurden anschließend manuell extrahiert und für den programmatischen Vergleich in einer Datei im selben Verzeichnis wie die Quellbilddatei festgehalten. Ein Beispiel dafür ist der Screenshot "zrs\_ZAMS\_filter-alarmgroup\_001" in \autoref{fig:screenshot_verschlagwortet}, welcher insgesamt 15 verschiedene Wörter beinhaltet.
|
||||
|
||||
\begin{figure}[ht]
|
||||
\centering
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\includegraphics[width=0.99\textwidth]{include/screenshots/zrs_ZAMS_filter-alarmgroup_001.png}
|
||||
\end{minipage}
|
||||
\hfill
|
||||
\begin{minipage}{0.45\textwidth}
|
||||
\lstinputlisting[numbers=none]{include/screenshots/zrs_ZAMS_filter-alarmgroup_001.json}
|
||||
\end{minipage}
|
||||
\caption{Ein Screenshot und die daraus manuell extrahierten Schlagworte.}
|
||||
\label{fig:screenshot_verschlagwortet}
|
||||
\end{figure}
|
||||
|
||||
\section{Programmablauf}
|
||||
|
||||
Die prototypische Implementierung besteht neben den oben genannten Komponenten aus einem ausführbaren Kommandozeilenprogramm zur Texterkennung und einem Programm zum Vergleich der Ergebnisse mit den manuell verschlagworteten Soll-Daten. Alle relevanten Daten werden in entsprechenden Ausgabeverzeichnissen festgehalten und dadurch für den jeweiligen nächsten Schritt verfügbar gemacht.
|
||||
|
||||
\subsection{Texterkennung}
|
||||
|
||||
Zu Beginn der Ausführung des Kommandozeilenprogramms wird für jedes zu verarbeitende Bild abhängig von den definierten Schwellenwertverfahren eine Reihe von Prozessoren angelegt. Dazu wurde der statische Teil der Bildverarbeitungskette gemäß \autoref{processor_chain_image} innerhalb der "EvaluationProcessor" Klasse definiert, wie in Programm \ref{prg:processor_definition_dynamic} auszugsweise dargestellt. Lediglich die zu evaluierenden Prozessoren für die jeweiligen Schwellwertverfahren können außerhalb der Klasse dynamisch definiert werden. Der EvaluationProcessor legt die erzeugten Ergebnisdaten, bestehend aus den gefundenen Wörtern und zugehörigen Metadaten wie die Confidence, auf Dateiebene ab. Um überprüfen zu können, welches Bild schlussendlich an das Texterkennungssystem übergeben wurde, werden auch die verarbeiteten Bilder nach der Binarisierung gespeichert.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
private static IEnumerable<EvaluationProcessor> MakeThresholdVariations()
|
||||
{
|
||||
for (int i = 4; i <= 24; i += 4)
|
||||
{
|
||||
yield return new(new ThresholdAdaptiveProcessor(i));
|
||||
}
|
||||
|
||||
for (int i = 20; i <= 80; i += 10)
|
||||
{
|
||||
yield return new(new ThresholdProcessor(i));
|
||||
}
|
||||
|
||||
yield return new(new AutoThresholdProcessor(AutoThresholdMethod.Kapur));
|
||||
yield return new(new AutoThresholdProcessor(AutoThresholdMethod.OTSU));
|
||||
yield return new(new AutoThresholdProcessor(AutoThresholdMethod.Triangle));
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "Program.cs": Definition der Thresholding Prozessoren.}
|
||||
\label{prg:processor_definition_dynamic}
|
||||
\end{program}
|
||||
|
||||
Ist die Erstellung der Bildbearbeitungsprozessoren abgeschlossen, wird jeder einzelne Prozessor über die Systembibliothek "System.Threading.Tasks" als eigene Ausführungseinheit (\engl{Task}) gestartet. In der Kommandozeile wird anschließend der aktuelle Status jedes Tasks angezeigt. Wurden alle Tasks abgeschlossen, wird das Programm beendet.
|
||||
|
||||
\subsection{Vergleich mit Soll-Daten}
|
||||
|
||||
Wurden die in den jeweiligen Screenshots erkannten Textdaten abgelegt, werden diese Daten im zweiten Kommandozeilenprogramm "ReportGenerator" nun mit den manuell verschlagworteten Daten verglichen und die Ergebnisse in einen Bericht (\engl{Report}) gespeichert.
|
||||
|
||||
Als zentrale Komponente für den Vergleich spielt die Berechnung der in \autoref{metriken} erklärten Metriken eine wesentliche Rolle. Wie in Programm \ref{prg:distance_levenshtein} ersichtlich, wird die Distanz zwischen zwei \csharp-Enumerables, seien es zwei Strings oder zwei Listen, über das Verfahren nach Levenshtein berechnet.
|
||||
|
||||
\begin{program}[!ht]
|
||||
\begin{CsCode}[numbers=none]
|
||||
public static double GetDistance<T>(T reference, T? hypothesis)
|
||||
where T : IEnumerable
|
||||
{
|
||||
var refArr = reference.Cast<object>().ToArray();
|
||||
var hypArr = hypothesis?.Cast<object>().ToArray() ?? Array.Empty<object>();
|
||||
|
||||
var distance = new int[refArr.Length + 1, hypArr.Length + 1];
|
||||
|
||||
for (var x = 0; x <= refArr.Length; x++)
|
||||
{
|
||||
distance[x, 0] = x;
|
||||
}
|
||||
|
||||
for (var y = 0; y <= hypArr.Length; y++)
|
||||
{
|
||||
distance[0, y] = y;
|
||||
}
|
||||
|
||||
for (var x = 0; x < refArr.Length; x++)
|
||||
{
|
||||
for (var y = 0; y < hypArr.Length; y++)
|
||||
{
|
||||
var cost = Equals(refArr[x], hypArr[y]) ? 0 : 1;
|
||||
|
||||
var c1 = distance[x, y] + cost; // Bottom left
|
||||
|
||||
var c2 = distance[x, y + 1] + 1; // Top left
|
||||
var c3 = distance[x + 1, y] + 1; // Bottom right
|
||||
|
||||
distance[x + 1, y + 1] = Min(c1, c2, c3); // Top right
|
||||
}
|
||||
}
|
||||
|
||||
return distance[refArr.Length, hypArr.Length];
|
||||
}
|
||||
\end{CsCode}
|
||||
\caption{Auszug aus Datei "Calculator.cs": Berechnung der Levenshtein-Distanz.}
|
||||
\label{prg:distance_levenshtein}
|
||||
\end{program}
|
||||
|
||||
Nach der Ermittlung der jeweiligen Distanzen auf Wort- \bzw Bildbasis werden sie mit den jeweiligen Ursprungsbildern, Prozessoren und den verwendeten Algorithmen in Bezug gesetzt. Die so aufbereiteten Ergebnisse werden anschließend an den ReportGenerator übergeben und in einen Bericht zusammengefasst.
|
||||
@@ -1,14 +1,11 @@
|
||||
\section{Evaluierung}
|
||||
\label{analyse}
|
||||
\chapter{Evaluierung}
|
||||
\label{evaluierung}
|
||||
|
||||
Nachdem die vorbereiteten Bilddaten an das Texterkennungssystem gemäß \autoref{implementierung} übergeben und die Ergebnisse ermittelt wurden, werden die extrahierten Textdaten nun mit den manuell erstellten "Soll-Daten" verglichen. Anhand der Statistik kann festgestellt werden, welche Vorgehensweise zu der besten Qualität führt. Um die Ergebnisse zu visualisieren, erstellt der in \autoref{components_reportgenerator} beschriebene "ReportGenerator" auf Basis der Bilddateinamen automatisch einen Bericht mit den Vergleichsdaten in Tabellenform. Der erstellte Bericht wird in verschiedene Kategorien unterteilt.
|
||||
|
||||
\subsection{Vergleich im Detail}
|
||||
\label{report_detailed}
|
||||
\section{Verarbeitungsstatistik}
|
||||
|
||||
\subsubsection{Processor Stats}
|
||||
|
||||
In der Sektion "Processor Stats", siehe \autoref{tbl:report_detailed_processorstats}, wird die Gesamtwortfehlerrate pro Bild mit dem jeweiligen Prozessor in Verhältnis gesetzt. Anhand der Metriken ist zu erkennen, dass gewisse Bilder aufgrund ihrer Eigenschaften (niedrige Auflösung, schwierige Farbgebung, etc.) von allen Prozessoren gleichermaßen schlecht erkannt werden. Jedoch fallen auch Spezialfälle auf: So werden beispielsweise die Textdaten in den Dialog-Knöpfen des Bilds "worldview\_zoom\_steps\_001" Dank eines falsch gewählten Schwellenwerts unkenntlich gemacht. Die Texterkennung schlägt fehl.
|
||||
In der Sektion "Processor Stats" (siehe \autoref{tbl:report_detailed_processorstats}), welche die Verarbeitungsstatistik enthält, wird die Gesamtwortfehlerrate pro Bild mit dem jeweiligen Prozessor in Verhältnis gesetzt. Anhand der Metriken ist zu erkennen, dass gewisse Bilder aufgrund ihrer Eigenschaften (niedrige Auflösung, schwierige Farbgebung, etc.) von allen Prozessoren gleichermaßen schlecht erkannt werden. Jedoch fallen auch Spezialfälle auf: So werden beispielsweise die Textdaten in den Dialog-Knöpfen des Bilds "worldview\_zoom\_steps\_001" Dank eines falsch gewählten Schwellenwerts unkenntlich gemacht. Die Texterkennung schlägt fehl.
|
||||
|
||||
\begin{table}[!ht]
|
||||
\centering
|
||||
@@ -17,9 +14,9 @@ In der Sektion "Processor Stats", siehe \autoref{tbl:report_detailed_processorst
|
||||
\label{tbl:report_detailed_processorstats}
|
||||
\end{table}
|
||||
|
||||
\subsubsection{Scan Results}
|
||||
\section{Ergebnisse}
|
||||
|
||||
Die Sektion "Scan Results" bildet den Abschluss des Detailvergleichs. Hier werden alle Verfahrenskombinationen einzeln und mit allen verfügbaren Daten aufgeführt.
|
||||
Die Sektion "Scan Results" (siehe \autoref{tbl:report_detailed_scanresults_stats} \bzw \autoref{tbl:report_detailed_scanresults_words}) zeigt die Verarbeitungsergebnisse auf Metrik- \bzw Wortbasis und bildet den Abschluss des Detailvergleichs. Hier werden alle Verfahrenskombinationen einzeln und mit allen verfügbaren Daten aufgeführt.
|
||||
|
||||
\begin{sidewaystable}[!ht]
|
||||
\centering
|
||||
@@ -35,7 +32,7 @@ Die Sektion "Scan Results" bildet den Abschluss des Detailvergleichs. Hier werde
|
||||
\label{tbl:report_detailed_scanresults_words}
|
||||
\end{table}
|
||||
|
||||
\subsection{Prozessoren im Überblick}
|
||||
\section{Prozessoren im Überblick}
|
||||
\label{report_processingsummary}
|
||||
|
||||
Neben dem Detailvergleich beinhaltet der generierte Bericht auch die "Processing Summary". Diese Kategorie zeigt eine kurze Übersicht aller Ergebnisse. Je nach Rubrik wird jeweils der Median \bzw Durchschnitt der \hyperref[metriken_cer]{Character Error Rate} und \hyperref[metriken_wer]{Word Error Rate} berechnet.
|
||||
1
main.tex
1
main.tex
@@ -103,6 +103,7 @@
|
||||
\include{chapters/c20_grundlagen/index}
|
||||
\include{chapters/c30_konzept/index}
|
||||
\include{chapters/c40_durchführung/index}
|
||||
\include{chapters/c50_evaluierung/index}
|
||||
\include{chapters/c80_zusammenfassung/index}
|
||||
|
||||
%%%-----------------------------------------------------------------------------
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
year = 2014,
|
||||
journal = {International Journal of Advance Research In Science And Engineering},
|
||||
volume = 3,
|
||||
number = 7
|
||||
number = 7,
|
||||
urldate = {2024-02-18}
|
||||
}
|
||||
@online{azurevision_home,
|
||||
title = {Azure AI Vision - Homepage},
|
||||
author = {Microsoft Corporation},
|
||||
url = {https://azure.microsoft.com/en-us/products/ai-services/ai-vision},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -18,7 +19,7 @@
|
||||
title = {Azure AI Vision - Pricing},
|
||||
author = {Microsoft Corporation},
|
||||
url = {https://azure.microsoft.com/en-gb/pricing/details/cognitive-services/computer-vision/},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -27,7 +28,7 @@
|
||||
author = {Wikimedia Commons},
|
||||
year = 2014,
|
||||
url = {https://commons.wikimedia.org/wiki/File:Bimodal-histogram.png},
|
||||
urldate = {2024-02-12}
|
||||
urldate = {2024-02-18}
|
||||
}
|
||||
@inbook{cc_platforms_comparison,
|
||||
title = {Comparison of Different Cloud Computing Platforms for Data Analytics},
|
||||
@@ -56,13 +57,14 @@
|
||||
doi = {church1995},
|
||||
issn = {0001-0782},
|
||||
url = {https://doi.org/church1995},
|
||||
urldate = {2024-02-18},
|
||||
numpages = 9
|
||||
}
|
||||
@online{copa-data_zenon,
|
||||
title = {COPA-DATA zenon - Homepage},
|
||||
author = {Ing. Punzenberger COPA-DATA GmbH},
|
||||
url = {https://www.copadata.com/en/product/zenon-software-platform-for-industrial-automation-energy-automation/},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -74,7 +76,7 @@
|
||||
doi = {10.5772/2575},
|
||||
isbn = {953-51-5669-1},
|
||||
url = {https://www.intechopen.com/books/2182},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
language = {eng},
|
||||
keywords = {Optical character recognition}
|
||||
}
|
||||
@@ -89,7 +91,7 @@
|
||||
title = {Google Cloud Vision - Homepage},
|
||||
author = {Google LLC},
|
||||
url = {https://cloud.google.com/vision},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -97,7 +99,7 @@
|
||||
title = {Google Cloud Vision - Pricing},
|
||||
author = {Google LLC},
|
||||
url = {https://cloud.google.com/vision/pricing},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -105,7 +107,7 @@
|
||||
title = {ImageMagick Homepage},
|
||||
author = {ImageMagick Studio LLC},
|
||||
url = {https://www.imagemagick.org/},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -113,7 +115,7 @@
|
||||
title = {IronOCR for .NET - Homepage},
|
||||
author = {Iron Software LLC},
|
||||
url = {https://ironsoftware.com/csharp/ocr/},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -121,21 +123,21 @@
|
||||
title = {Anyline - Homepage},
|
||||
author = {Anyline GmbH},
|
||||
url = {https://anyline.com},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@online{nuget_magicknet,
|
||||
title = {Magick.NET - NuGet},
|
||||
url = {https://www.nuget.org/packages/Magick.NET.Core},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@online{nuget_tesseract,
|
||||
title = {Tesseract - NuGet},
|
||||
url = {https://www.nuget.org/packages/Tesseract},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -144,7 +146,8 @@
|
||||
author = {Islam, Noman and Islam, Zeeshan and Noor, Nazia},
|
||||
year = 2017,
|
||||
journal = {arXiv preprint},
|
||||
url = {https://doi.org/10.48550/arXiv.1710.05703}
|
||||
url = {https://doi.org/10.48550/arXiv.1710.05703},
|
||||
urldate = {2024-02-18}
|
||||
}
|
||||
@article{kalyanathaya2019advances,
|
||||
title = {Advances in natural language processing: a survey of current research trends, development tools and industry applications},
|
||||
@@ -197,7 +200,8 @@
|
||||
volume = 9,
|
||||
number = 1,
|
||||
doi = {10.1109/TSMC.1979.4310076},
|
||||
url = {https://ieeexplore.ieee.org/document/4310076}
|
||||
url = {https://ieeexplore.ieee.org/document/4310076},
|
||||
urldate = {2024-02-18}
|
||||
}
|
||||
@inproceedings{park2008empirical,
|
||||
title = {An empirical analysis of word error rate and keyword error rate.},
|
||||
@@ -221,7 +225,7 @@
|
||||
booktitle = {Ninth international conference on document analysis and recognition (ICDAR 2007)},
|
||||
volume = 2,
|
||||
url = {https://ieeexplore.ieee.org/document/4376991},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = 2007,
|
||||
organization = {IEEE},
|
||||
langid = {ngerman}
|
||||
@@ -238,7 +242,7 @@
|
||||
@online{tessdoc,
|
||||
title = {Tesseract Documentation},
|
||||
url = {https://tesseract-ocr.github.io/},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -254,7 +258,7 @@
|
||||
title = {Amazon Textract - Homepage},
|
||||
author = {Amazon Web Services, Inc.},
|
||||
url = {https://aws.amazon.com/textract},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -262,7 +266,7 @@
|
||||
title = {Amazon Textract - Pricing},
|
||||
author = {Amazon Web Services, Inc.},
|
||||
url = {https://aws.amazon.com/textract/pricing/},
|
||||
urldate = {2024-02-12},
|
||||
urldate = {2024-02-18},
|
||||
date = {2023-05-23},
|
||||
language = {eng}
|
||||
}
|
||||
@@ -270,7 +274,7 @@
|
||||
title = {The Old Bailey and OCR: Benchmarking AWS, Azure, and GCP with 180,000 Page Images},
|
||||
author = {William Ughetta and Kernighan, {Brian W.}},
|
||||
year = 2020,
|
||||
month = sep,
|
||||
month = 9,
|
||||
day = 29,
|
||||
publisher = {Association for Computing Machinery, Inc},
|
||||
doi = {10.1145/3395027.3419595},
|
||||
@@ -281,7 +285,7 @@
|
||||
title = {A Statistical Approach to Automatic OCR Error Correction in Context},
|
||||
author = {Tong, Xiang and Evans, David A.},
|
||||
year = 1996,
|
||||
month = {jun},
|
||||
month = 6,
|
||||
booktitle = {Fourth Workshop on Very Large Corpora},
|
||||
publisher = {Association for Computational Linguistics},
|
||||
address = {Herstmonceux Castle, Sussex, UK},
|
||||
@@ -293,7 +297,7 @@
|
||||
author = {Wikimedia Commons},
|
||||
year = 2014,
|
||||
url = {https://commons.wikimedia.org/wiki/File:Tips-histogram1.png},
|
||||
urldate = {2024-02-12}
|
||||
urldate = {2024-02-18}
|
||||
}
|
||||
@inproceedings{wang2003word,
|
||||
title = {Is word error rate a good indicator for spoken language understanding accuracy},
|
||||
@@ -380,3 +384,12 @@
|
||||
journal={arXiv preprint arXiv:1003.5893},
|
||||
year={2010}
|
||||
}
|
||||
@article{kumar2017noise,
|
||||
title={Noise removal and filtering techniques used in medical images},
|
||||
author={Kumar, Nalin and Nachamai, M},
|
||||
journal={Oriental Journal of Computer Science and Technology},
|
||||
volume={10},
|
||||
number={1},
|
||||
pages={103--113},
|
||||
year={2017}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ Einleitung (ohne Einleitesatz)
|
||||
Zielsetzung
|
||||
Aufbau der Arbeit (inkl. Vorgehensweise)
|
||||
*Was ist in welchem Bereich beschrieben? Zuerst Stand der Technik, dann .... So wurde vorgegangen und das wurde dort und dort beschrieben. Bezieht sich auf den Inhalt der Bachelorarbeit.*
|
||||
Eigenschaften von Screenshots (erste zwei Sätze von 3.1.1.1. aus Annahmen)
|
||||
Eigenschaften von Screenshots (erste zwei Sätze von 3.1.1.1. aus Annahmen)
|
||||
Beispielscreenshots in Einleitung
|
||||
Grundlagen (umbenennen in Stand der Technik?)
|
||||
Stand der Technik / Texterkennungssysteme - ein Überblick
|
||||
|
||||
Reference in New Issue
Block a user