Zum Hauptinhalt springen
Der Einfachheit halber wird in diesem Beispiel ein einseitiges Dokument verwendet.
Bei der Dokumentenverarbeitung gibt es häufig Situationen, in denen es nicht ausreicht, die Position von Elementen relativ zu anderen Elementen anhand von „oberhalb - unterhalb - rechts - links“ zu beschreiben. Das kann zum Beispiel vorkommen, wenn sich im Suchbereich mehrere Objekte befinden, die den Suchbedingungen entsprechen. In solchen Fällen werden zusätzliche Unterscheidungsmerkmale benötigt, insbesondere der Abstand zwischen den Objekten. Für diese Zwecke bietet FlexiLayout Studio die Funktion FuzzyQuality sowie die Funktionen der Gruppe Nearest (Nearest, NearestX, NearestY).

Wie sich die Funktionen Nearest und FuzzyQuality unterscheiden

Diese Funktionen werden unterschiedlich eingesetzt. Die Funktion Nearest kann nur im Feld Advanced pre-search relations verwendet werden. Sie legt fest, dass das Programm unter mehreren Hypothesen eines Elements diejenige auswählen muss, die dem in den Eigenschaften der Funktion Nearest angegebenen Element oder Punkt im Bild am nächsten ist. Im Feld Advanced pre-search relations des Elements kann nur eine Funktion aus der Gruppe Nearest verwendet werden. Nach ihrer Ausführung bleibt nur eine Hypothese übrig; dies geschieht in der Phase der Hypothesengenerierung, also bevor der im Feld Erweiterte Nach-Suchbeziehungen angegebene Code ausgeführt wird. Der Parameter Minimum quality, der die Mindestqualität von Hypothesen für das Element angibt, kann für die Elemente StaticText, Zeichenkette, Paragraph, Date und Separator angegeben werden. Es gibt keine Garantie dafür, dass die verbleibende Hypothese die beste ist (und dem gewünschten Objekt im Bild entspricht), da Erweiterte Nach-Suchbeziehungen für die Zuweisung eines Qualitätswerts an eine Hypothese sehr wichtig sind. Bei Verwendung der Funktion Nearest erfolgt die Auswahl der Hypothese in der Phase der Hypothesengenerierung und basiert auf der Nähe zu einem Punkt, nicht auf der Qualität der Hypothese. Wenn die im Abschnitt Erweiterte Nach-Suchbeziehungen angegebenen Eigenschaften für die korrekte Auswahl der Hypothese wichtig sind, sollte daher statt der Funktionen der Gruppe Nearest die Funktion FuzzyQuality verwendet werden. Die Funktion FuzzyQuality kann nur im Abschnitt Erweiterte Nach-Suchbeziehungen verwendet werden. Anders als die Funktionen der Gruppe Nearest wählt sie keine einzelne Hypothese aus, sondern beeinflusst die Gesamtqualität aller generierten Hypothesen anhand der Eigenschaften dieser Hypothesen und der Parameter der Funktion FuzzyQuality. Außerdem kann die Funktion FuzzyQuality für ein einzelnes Element im Feld Erweiterte Nach-Suchbeziehungen mehrfach verwendet werden. Das bedeutet, dass auf eine Hypothese mehrere unterschiedliche Bedingungen mit verschiedenen Qualitätswerten angewendet werden können. Alle Werte werden multipliziert, um die Post-search quality der Hypothese zu bestimmen. Die Funktion FuzzyQuality sieht wie folgt aus:
FuzzyQuality: x, {f1, f2, f3, f4};
Der Algorithmus funktioniert wie folgt: Die Funktion prüft, ob der Wert des Parameters x zu dem durch die Parameter f1, f2, f3, f4 definierten unscharfen Intervall gehört. Die Bedeutung dieses unscharfen Intervalls ist ähnlich wie bei den unscharfen Intervallen, die für einige der Parameter des Elements Zeichenkette angegeben werden.

Das Beispielprojekt FuzzyAndNearest

Dieses Beispiel zeigt, wie die Funktionen Nearest und FuzzyQuality auf den folgenden Bildern verwendet werden können.
Beispiel für ein semi-strukturiertes Rechnungsdokument mit den Feldern Rechnungsnummer und Rechnungsdatum in einem LayoutBeispiel für ein semi-strukturiertes Rechnungsdokument mit den Feldern Rechnungsnummer und Rechnungsdatum in einem anderen Layout
Beispiel für ein semi-strukturiertes Rechnungsdokument mit den Feldern Rechnungsnummer und Rechnungsdatum in einem anderen LayoutBeispiel für ein semi-strukturiertes Rechnungsdokument mit den Feldern Rechnungsnummer und Rechnungsdatum in einem anderen Layout
Wie die Bilder zeigen, ist das Rechnungsdokument semi-strukturiert: Die Anordnung der Felder unterscheidet sich von Bild zu Bild. Ziel ist es, die Felder „Rechnungsnummer“ und „Rechnungsdatum“ zu erkennen. Dies erfolgt im Projekt 1.fsp (Ordner %public%\ABBYY\FlexiCapture\12.0\Samples\FLS\Tips and Tricks\FuzzyAndNearest \Project1). Um die FlexiLayout-Struktur zu optimieren und der Logik hinter der Anordnung der gesuchten Felder im Dokument zu folgen, fasst das Projekt alle gesuchten Elemente in einem zusammengesetzten Element, InvoiceGroup, zusammen. Die Erstellung des FlexiLayouts könnte mit einem Element beginnen, das die Suchbedingungen für die Bezeichnung des Feldes „Rechnungsnummer“ beschreibt. Eine Analyse der Bilder zeigt jedoch, dass das Wort „Invoice“, aus dem die Bezeichnung besteht, im Dokument mehrmals vorkommt. Da sich die relative Position der Felder jedes Mal ändert, ist es unmöglich, Bedingungen anzugeben, die eine korrekte Erkennung des Wortes „Invoice“ garantieren. Es kann zum Beispiel auch in der Bezeichnung „Invoice date“ vorkommen. Um solche Verwechslungen zu vermeiden, beginnt die Beschreibung mit der Bezeichnung des Datumsfelds und verwendet dazu ein Static Text-Element namens DateHeader. Das Feld Search text gibt zwei Werte für die Bezeichnung an: Invoicedate:|Invoicedate (Auflistung der Varianten der Bezeichnung, wie sie auf den Bildern vorkommen). Die Groß-/Kleinschreibung der Bezeichnung spielt dabei keine Rolle.
Weitere Informationen dazu, warum Sie beide Varianten angeben müssen, finden Sie unter Mehrere statische Textwerte festlegen. Nach statischem Text mit ähnlichen Werten suchen.

Suche nach dem Datumsfeld mit einem Array von Rechtecken

Die Suche nach dem Datumsfeld basiert auf dem Feldnamen. Das Projekt enthält eine Gruppe DateAlternative, die aus zwei Elementen besteht: einem Date-Element, um nach dem Datumsfeld in einem der angegebenen Formate zu suchen, und einem Zeichenkette-Element für den Fall, dass das Format des gesuchten Felds anders ist.
Eine ausführliche Beschreibung zum Erstellen eines FlexiLayouts für die Datumssuche finden Sie unter Datumssuche nach Erkennung mit hoher oder niedriger Qualität.
Wie die Abbildungen zeigen, kann sich das Datumsfeld entweder rechts neben dem Namen “Rechnungsdatum” oder darunter befinden. Wenn im Feld Relations Standardsuchbedingungen festgelegt sind (diese werden im Projekt angezeigt, sind aber deaktiviert), ist der Suchbereich zu groß und kann Felder einschließen, die fälschlicherweise als Datumsfeld erkannt werden könnten (ein Beispiel ist in der Abbildung zu sehen). Das kann zum Beispiel passieren, wenn das Datum nicht mit dem für das Date-Element angegebenen Format übereinstimmt.
Screenshot in ABBYY FlexiLayout Studio, der zeigt, wie standardmäßige Suchbedingungen in Relations den Suchbereich des Datumsfelds zu groß machen und andere Felder einschließen, die mit dem Feld Rechnungsdatum verwechselt werden können.
Damit das Programm den unerwünschten Bereich nicht analysiert, verwendet das Projekt eine alternative Methode. Das Feld Advanced pre-search relations enthält den folgenden Code:
let Header = InvoiceGroup.DateHeader;
if not Header.IsNull then
{ let rect1 = Rect (Header.Rect.Right, Header.Rect.Top-20dt,
PageRect.Right, Header.Rect.Bottom+20dt);
let rect2 = Rect (Header.Rect.Left - 200dt, Header.Rect.Bottom,
Header.Rect.Right + 150dt, Header.Rect.Bottom+200dt);
RectArray ar;
ar = RectArray ( rect1 );
ar.Add ( rect2 );
RestrictSearchArea( ar );
}
else
{ Above: PageRect.Top + PageRect.Height/2;
}
Der Code prüft, ob der Name des Datumsfelds gefunden wurde. Wenn ja, wird der Suchbereich als Array von Rechtecken festgelegt (im Beispiel 2 Rechtecke). Mit einem Rechteck wird rechts neben dem Namen nach dem Datum gesucht, mit dem anderen darunter. Wird der Name nicht gefunden, wird die Suche in der oberen Bildhälfte ausgeführt. Auf einer Seite, für die die Suchbedingungen im Abschnitt Relations angegeben wurden, hat der Suchbereich nach Ausführung dieses Codes keine rechteckige Form. Wie in der Abbildung zu sehen ist, wurden alle unerwünschten Objekte daraus entfernt.
Die erste Zeile des Codes (let Header = InvoiceGroup.DateHeader;) vereinfacht den Code, indem sie die Variable Header definiert und ihr den Wert des Elements DateHeader zuweist.
Screenshot in ABBYY FlexiLayout Studio, der den nicht rechteckigen Suchbereich des Datumsfelds zeigt, der durch den Code RestrictSearchArea erzeugt wurde und aus dem alle unerwünschten Objekte entfernt wurden.
Dieser Code wird für das Element DateAsString nicht wiederholt. Stattdessen enthält sein Abschnitt Advanced pre-search relations die folgende Suchbedingung:
if not Date.IsNull then Dontfind();
else RestrictSearchArea (Date.Rect);
Das bedeutet, dass die Suche, wenn das Element Date nicht erkannt wird, in dem Rechteck ausgeführt wird, das den Suchbereich des Elements Date umgibt.
Um den Suchbereich des Elements DateAsString als Array von Rechtecken anzugeben, duplizieren Sie statt RestrictSearchArea (Date.Rect) den entsprechenden Code aus dem Abschnitt Advanced pre-search relations des Elements Date.

Den Namen des Felds „Invoice“ mit Exclude und NearestY erkennen

Das Projekt enthält außerdem ein Static Text-Element (mit dem Namen InvoiceHeader), um den Namen des Felds “Rechnungsnummer” mit dem gesuchten Wert “Invoice” zu erkennen. Da das Dokument nicht strukturiert ist, können keine spezifischen Suchbedingungen angegeben werden. Sobald der Abgleich des FlexiLayouts abgeschlossen ist, sehen Sie, dass der Name nur auf der ersten Seite korrekt erkannt wurde. Auf den Seiten 2 und 4 wurde das Wort “Invoice” fälschlicherweise als Name des Datumsfelds erkannt. Auf Seite 3 wurde es am unteren Seitenrand gefunden. Dem Optimierungsalgorithmus zufolge wurden die anderen Hypothesen für den Namen nicht generiert, obwohl das Wort “Invoice” im Bild dreimal vorkommt.
Weitere Informationen zur optimalen Suche nach Elementen in der Gruppe finden Sie unter Optimizing group element search.
Zur Lösung dieser Probleme wird die folgende Methode verwendet. Um die Region des Namens des Datumsfelds aus dem Suchbereich des Feldnamens “Invoice” auszuschließen, wird das Element DateHeader zum Abschnitt Exclude regions of elements hinzugefügt (siehe folgende Abbildung).
Wenn das FlexiLayout nicht mit dem Namen DateHeader, sondern mit dem Namen InvoiceHeader begonnen hätte, könnte die Funktion Exclude nicht verwendet werden, da mit dieser Funktion nur Elemente ausgeschlossen werden können, die sich im Projektbaum oberhalb des aktuellen Elements befinden.
Um die unerwünschte Erkennung des Worts “Invoice” am unteren Seitenrand auszuschließen, wird im Abschnitt Advanced pre-search relations der folgende Code geschrieben.
NearestY: PageRect.Top;
Dieser Code weist das Programm an, nach dem Element zu suchen, das dem oberen Seitenrand am nächsten liegt.
Screenshot des Abschnitts Advanced pre-search relations in ABBYY FlexiLayout Studio mit dem Code NearestY: PageRect.Top, der nach dem Element des Feldnamens Invoice sucht, das dem oberen Seitenrand am nächsten liegt.
Sobald das FlexiLayout abgeglichen wurde, sehen Sie, dass diese Methode auf Seite 2 fehlgeschlagen ist, weil der Name des Datumsfelds hier stark verrauscht war und nicht erkannt wurde. Auf dieser Seite gilt die in der Funktion Nearest angegebene Bedingung für beide Strings “Invoice”, weil sie sich auf derselben Höhe befinden. Da die Erkennungsqualität der Strings “Invoice” in beiden Fällen gut ist, erzeugte der Optimierungsalgorithmus nur eine Hypothese statt zwei separater. Leider ist diese Hypothese nicht korrekt.

Suche nach der Rechnungsnummer mit Nearest

Um das Feld “Rechnungsnummer” zu erkennen, verwendet das Project ein Element vom Typ Zeichenkette namens InvoiceNumber. Wie beim Element für das Datumsfeld werden die Suchbedingungen für das Feld “Rechnungsnummer” im Abschnitt Advanced pre-search relations festgelegt. Der Suchbereich für dieses Element ist ein Array von Rechtecken.
let Header = InvoiceGroup.InvoiceHeader;
if not Header.IsNull then
{ let rect1 = Rect (Header.Rect.Right, Header.Rect.Top-20dt,
PageRect.Right, Header.Rect.Bottom+20dt);
let rect2 = Rect (Header.Rect.Left - 200dt, Header.Rect.Bottom,
Header.Rect.Right + 150dt, Header.Rect.Bottom+200dt);
RectArray ar;
ar = RectArray( rect1 );
ar.Add( rect2 );
RestrictSearchArea( ar );
}
else
{ Above: PageRect.Top + PageRect.Height/2;
}
Nearest: Header;
Zusätzlich enthält der Code noch eine weitere Einschränkung, die dem Programm mitteilt, dass das InvoiceNumber-Element dem Namenselement am nächsten liegt. Nach dem Ausführen des Matchings können Sie sehen, dass das Feld “Rechnungsnummer” auf den Seiten 2 und 4 falsch erkannt wurde. Auf Seite 4 wurde es falsch erkannt, obwohl die Feldbezeichnung korrekt erkannt wurde.
Als Alternative (für die Bilder in diesem Projekt) zu Nearest: Header; könnten Sie NearestY: Header.Rect.YCenter; schreiben, um dem Programm mitzuteilen, dass das gesuchte Feld dem Mittelpunkt des Namens vertikal am nächsten ist.Dies könnte das Problem der fehlerhaften Erkennung des Feldes “Rechnungsnummer” auf Seite 4 lösen. Auf Seite 5 hilft es jedoch nicht, weil das gesuchte Feld nach der fehlerhaften Erkennung des Namens “Rechnungsnummer” im Datumsfeld erkannt wird.

Nearest durch FuzzyQuality-Strafwerte ersetzen

Sehen wir uns nun an, wie die Funktion FuzzyQuality in einer solchen Situation verwendet werden kann. Dies wird im Projekt 2.fsp demonstriert (Ordner FuzzyAndNearest\Project2). Die Einstellungen dieses Projekts sind nahezu identisch mit denen des zuvor beschriebenen Projekts. Es gibt jedoch einen wesentlichen Unterschied: Die Funktion Nearest wird im Abschnitt Advanced pre-search relations nicht verwendet. Stattdessen enthält der Abschnitt Erweiterte Nach-Suchbeziehungen den folgenden Code:
if not IsNull then
{ FuzzyQuality: Rect.Top - PageRect.Top, {0,0,0,50000} * dt;
FuzzyQuality: 500dt-Width, {0,0,0,100000} * dt;
if not InvoiceHeader.IsNull then
{ FuzzyQuality: Rect.XCenter - InvoiceHeader.Rect.XCenter, {-10000,0,0,50000} *dt;
FuzzyQuality: Rect.YCenter - InvoiceHeader.Rect.YCenter, {-10000,0,0,10000} *dt;
}
}
Diese Methode beeinflusst die Quality aller Hypothesen, ohne eine davon auszuschließen. Die Auswahl der besten Kette erfolgt für jede Kette einzeln, indem die Qualitätswerte aller zugehörigen Elementhypothesen miteinander multipliziert werden. Die Zeile FuzzyQuality: Rect.Top - PageRect.Top, {0,0,0,50000} * dt; bedeutet, dass, wenn eine Nicht-Null-Hypothese erzeugt wird (die Prüfung if not IsNull wird zuerst ausgeführt), der Abstand zwischen der Position des Elements und dem oberen Rand der Seite bestimmt wird. Das heißt, die Differenz (Rect.Top - PageRect.Top) wird berechnet, und das Programm prüft, ob diese Differenz in das Intervall {0, 0, 0, 50000}*dt fällt. Eine solche Intervallbeschreibung bedeutet, dass die Qualitätsstrafe direkt vom Abstand zwischen dem Element und dem oberen Rand der Seite abhängt: Je größer der Abstand, desto höher die Strafe. Wie in Abbildung (a) gezeigt, entspricht bei den angegebenen Parameterwerten die maximale Strafe (1) einem Abstand von 50000dt, während ein Abstand von 1000 Dots (1 Dot entspricht 1/300 Zoll) eine Strafe von 0.02 und ein Abstand von 100dt eine Strafe von 0.002 bedeutet.
Achten Sie bei der Auswahl der Parameter, die die Grenzen des Intervalls festlegen (insbesondere wenn es mehrere Elementprüfungen mit der Funktion FuzzyQuality gibt), darauf, dass sie die richtige Hypothese nicht so stark bestrafen, dass ihre endgültige Quality niedriger wird als die einer Nullhypothese.Wenn die Quality aller Hypothesen (einschließlich der korrekten) niedriger ist als der Quality-Wert einer Nullhypothese, kann die Nullhypothese ausgewählt werden, das heißt, das Element wird nicht erkannt.
Diagramm, das zeigt, wie die Qualitätsstrafe mit dem Abstand zwischen dem Element und dem oberen Rand der Seite zunimmt, wobei ein Abstand von 50000dt die maximale Strafe von 1 ergibt.
(a) Die Zeile FuzzyQuality: 500dt - Width, {0,0,0,100000}*dt; bedeutet, dass das Programm die Differenz zwischen 500dt und der Breite des erkannten Objekts berücksichtigt, das der Hypothese entspricht. Das heißt, die Differenz (500dt - Width) wird berechnet, und das Programm prüft, ob diese Differenz in das Intervall {0, 0, 0, 100000}*dt fällt. Je schmaler das Objekt, desto höher die Strafe, sodass längere Rechnungsnummern bevorzugt werden. Diese Einschränkung kann verwendet werden, wenn das Bild verrauscht ist. Wenn das Rauschen als Zeichen aus dem angegebenen Alphabet erkannt wird (wie beispielsweise auf Seite 2 zu sehen), sollte seine Hypothese bestraft werden, um sie von der weiteren Analyse auszuschließen.
Der Wert 500dt wird anhand einer visuellen Prüfung gewählt, unter der Annahme, dass die String-Länge im Feld “Rechnungsnummer” diesen Wert nicht überschreitet. Die hier angegebenen Parameter legen fest, dass die maximale Strafe (0.005) einer Feldbreite von null für das Feld “Rechnungsnummer” entspricht. Für alle anderen Breiten zwischen 0 und 500dt wären die Qualitätsstrafen geringer.
Die Zeile FuzzyQuality: Rect.XCenter - InvoiceHeader.Rect.XCenter, {-10000,0,0,50000} *dt; bedeutet, dass, wenn eine Nicht-Null-Hypothese für das Element mit dem Namen des Feldes „Rechnungsnummer“ erzeugt wird (zuerst wird die Prüfung if not InvoiceHeader.IsNull ausgeführt), der Abstand zwischen dem Mittelpunkt des erkannten Elements InvoiceNumber und dem Mittelpunkt des Namens InvoiceHeader bestimmt wird. Die Differenz (Rect.XCenter - InvoiceHeader.Rect.XCenter) wird berechnet, und das Programm prüft, ob diese Differenz in das Intervall {-10000, 0, 0, 50000}*dt fällt. Diese Beschreibung berücksichtigt auch die Möglichkeit, dass sich das Feld „Rechnungsnummer“ unterhalb des Namens befinden kann. In diesem Fall gilt: Je weiter die Elemente voneinander entfernt sind, desto höher ist die Strafe für die entsprechende Hypothese. Hypothesen, die davon ausgehen, dass sich die Nummer rechts vom Namen befindet, werden nicht so stark bestraft wie diejenigen, die davon ausgehen, dass sich die Nummer unterhalb des Namens befindet, da die „rechte“ Anordnung des Feldes „Rechnungsnummer“ und seines Namens deutlich häufiger vorkommt. Wie in Abbildung (b) gezeigt, entspricht bei den angegebenen Parametern für die linken und rechten Intervallgrenzen die maximale Strafe (1) einer Verschiebung des Feldes „Rechnungsnummer“ relativ zum Namensfeld um 10000dt nach links oder um 50000dt nach rechts. Eine Verschiebung um 1000 dots wird mit 0.1 bestraft, wenn es sich um eine Verschiebung nach „links“ handelt, oder mit 0.02, wenn es sich um eine Verschiebung nach „rechts“ handelt. Entsprechend wird eine Verschiebung um 100 dots mit 0.01 bestraft, wenn es sich um eine Verschiebung nach „links“ handelt, oder mit 0.002, wenn es sich um eine Verschiebung nach „rechts“ handelt.
Diagramm, das die Quality-Strafe für die horizontale Verschiebung des Feldes „Rechnungsnummer“ relativ zu seinem Namen zeigt, wobei die maximale Strafe von 1 einer Verschiebung um 10000dt nach links oder 50000dt nach rechts entspricht.
(b) Die Zeile FuzzyQuality: Rect.YCenter - InvoiceHeader.Rect.YCenter, {-10000,0,0,10000} *dt; ist mit der vorherigen identisch. Sie ist jedoch für Fälle vorgesehen, in denen sich das Feld „Rechnungsnummer“ auf derselben horizontalen Ebene wie das Namensfeld oder sogar leicht darüber befindet. Die Strafen sind hier für jede vertikale Verschiebung gleich. Die Intervallgrenzen werden nach derselben Logik festgelegt: Hypothesen, die das Datenfeld rechts von seinem Namen finden, sollen priorisiert werden. Das Projekt zeigt jedoch, dass diese Einstellungen die korrekte Erkennung der Rechnungsnummer auch dann nicht verhindert haben, wenn sie sich unterhalb des Namens befand (Seite 3). Nach dem Abgleich des FlexiLayouts mit allen Seiten können Sie sehen, dass die beiden gesuchten Felder erfolgreich erkannt wurden. Zusammenfassend ist die Funktion FuzzyQuality effizienter und flexibler als die Funktionen der Gruppe Nearest, was besonders bei der Verarbeitung semi-strukturierter Dokumente wichtig ist.