Bildverarbeitung zur Verbesserung der OCR-Genauigkeit von Tesseract


145

Ich habe Tesseract verwendet, um Dokumente in Text umzuwandeln. Die Qualität der Dokumente ist sehr unterschiedlich und ich suche nach Tipps, welche Art der Bildverarbeitung die Ergebnisse verbessern kann. Ich habe festgestellt, dass stark pixeliger Text - zum Beispiel der von Faxgeräten erzeugte - für Tesseract besonders schwer zu verarbeiten ist - vermutlich verwechseln all diese gezackten Kanten der Zeichen die Formerkennungsalgorithmen.

Welche Art von Bildverarbeitungstechniken würde die Genauigkeit verbessern? Ich habe eine Gaußsche Unschärfe verwendet, um die Pixelbilder zu glätten, und eine kleine Verbesserung festgestellt, aber ich hoffe, dass es eine spezifischere Technik gibt, die bessere Ergebnisse liefert. Angenommen, ein Filter wurde auf Schwarzweißbilder abgestimmt, wodurch unregelmäßige Kanten geglättet werden, gefolgt von einem Filter, der den Kontrast erhöht, um die Zeichen deutlicher zu machen.

Irgendwelche allgemeinen Tipps für jemanden, der ein Anfänger in der Bildverarbeitung ist?

Antworten:


103
  1. Fix DPI (falls erforderlich) 300 DPI sind mindestens
  2. Textgröße korrigieren (zB 12 pt sollten in Ordnung sein)
  3. versuchen Sie, Textzeilen zu korrigieren (Deskew- und Dewarp-Text)
  4. Versuchen Sie, die Beleuchtung des Bildes zu korrigieren (z. B. kein dunkler Teil des Bildes).
  5. Bild binarisieren und rauschen

Es gibt keine universelle Befehlszeile, die für alle Fälle geeignet ist (manchmal müssen Sie das Bild verwischen und schärfen). Sie können TEXTCLEANER jedoch über Freds ImageMagick-Skripte ausprobieren .

Wenn Sie kein Fan der Befehlszeile sind, können Sie möglicherweise versuchen, opensource scantailor.sourceforge.net oder den kommerziellen Buchrestaurator zu verwenden .


6
Und es gibt eine illustrierte Anleitung dazu: code.google.com/p/tesseract-ocr/wiki/ImproveQuality
iljau

2
Beachten Sie, dass das verknüpfte Skript nur für Linux verfügbar zu sein scheint.
Zoran Pavlovic

1
Dies ist nicht wahr - dies ist ein Bash-Skript. Wenn Sie bash und ImageMagick installiert haben, läuft es auch unter Windows. Bash könnte als Teil einer anderen nützlichen Software installiert werden, z. B. git oder msys2 ...
user898678

6
@iljau Da ist nach Github gezogen. Wiki-Seite ist bei: github.com/tesseract-ocr/tesseract/wiki/ImproveQuality
Hometoast

2
Die Tesseract-Dokumente wurden erneut nach tesseract-ocr.github.io/tessdoc/ImproveQuality
Nobody

73

Ich bin kein OCR-Experte. Aber ich musste diese Woche Text aus einem JPG konvertieren.

Ich begann mit einem kolorierten JPG mit 445 x 747 Pixel. Ich habe sofort versucht, dies zu tun, und das Programm hat fast nichts konvertiert. Ich ging dann zu GIMP und tat Folgendes. Bild> Modus> Graustufenbild> Skalierungsbild> 1191x2000 Pixel Filter> Verbessern> Unscharfe Maske mit Werten von Radius = 6,8, Betrag = 2,69, Schwellenwert = 0 Ich habe dann als neues JPG bei 100% Qualität gespeichert.

Tesseract konnte dann den gesamten Text in eine TXT-Datei extrahieren

Gimp ist dein Freund.


11
+1 Ich bin deinen Schritten gefolgt und habe eine große Verbesserung erzielt. Dank
OnOF

1
Ich habe auch den Eindruck, dass Tesseract besser funktioniert, wenn Sie die Eingabe in eine TIFF-Datei konvertieren und Tesseract das TIFF geben (anstatt Tesseract zu bitten, die Konvertierung für Sie durchzuführen). ImageMagick kann die Konvertierung für Sie durchführen. Dies ist mein anekdotischer Eindruck, aber ich habe ihn nicht sorgfältig getestet, daher könnte er falsch sein.
DW

+1 Der Filter "Unscharfe Maske" hat mir wirklich den Tag gemacht. Ein weiterer Schritt, der mir geholfen hat: Wählen Sie mit dem Tool "Fuzzy-Auswahl" den Hintergrund aus und drücken Sie die Entf-Taste, um ihn aufzuhellen
Davide,

Ich bin bei diesem Bildverarbeitungsproblem festgefahren, bevor Tesseract erkannt wird. Stackoverflow.com/questions/32473095/… Können Sie mir hier weiterhelfen?
Hussain

Nee. Ich habe versucht, es größer zu machen, und es in Graustufen zu setzen, scheint mir nichts positives Ergebnis zu geben. Seufz :( Überprüfen Sie dieses Ziel: freesms4us.com/…
gumuruh

30

Drei Punkte zur Verbesserung der Lesbarkeit des Bildes: 1) Ändern Sie die Größe des Bildes mit variabler Höhe und Breite (multiplizieren Sie 0,5 und 1 und 2 mit Bildhöhe und -breite). 2) Konvertieren Sie das Bild in das Graustufenformat (Schwarzweiß). 3) Entfernen Sie die Rauschpixel und machen Sie es klarer (Filtern Sie das Bild).

Siehe folgenden Code:

//Resize
  public Bitmap Resize(Bitmap bmp, int newWidth, int newHeight)
        {

                Bitmap temp = (Bitmap)bmp;

                Bitmap bmap = new Bitmap(newWidth, newHeight, temp.PixelFormat);

                double nWidthFactor = (double)temp.Width / (double)newWidth;
                double nHeightFactor = (double)temp.Height / (double)newHeight;

                double fx, fy, nx, ny;
                int cx, cy, fr_x, fr_y;
                Color color1 = new Color();
                Color color2 = new Color();
                Color color3 = new Color();
                Color color4 = new Color();
                byte nRed, nGreen, nBlue;

                byte bp1, bp2;

                for (int x = 0; x < bmap.Width; ++x)
                {
                    for (int y = 0; y < bmap.Height; ++y)
                    {

                        fr_x = (int)Math.Floor(x * nWidthFactor);
                        fr_y = (int)Math.Floor(y * nHeightFactor);
                        cx = fr_x + 1;
                        if (cx >= temp.Width) cx = fr_x;
                        cy = fr_y + 1;
                        if (cy >= temp.Height) cy = fr_y;
                        fx = x * nWidthFactor - fr_x;
                        fy = y * nHeightFactor - fr_y;
                        nx = 1.0 - fx;
                        ny = 1.0 - fy;

                        color1 = temp.GetPixel(fr_x, fr_y);
                        color2 = temp.GetPixel(cx, fr_y);
                        color3 = temp.GetPixel(fr_x, cy);
                        color4 = temp.GetPixel(cx, cy);

                        // Blue
                        bp1 = (byte)(nx * color1.B + fx * color2.B);

                        bp2 = (byte)(nx * color3.B + fx * color4.B);

                        nBlue = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

                        // Green
                        bp1 = (byte)(nx * color1.G + fx * color2.G);

                        bp2 = (byte)(nx * color3.G + fx * color4.G);

                        nGreen = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

                        // Red
                        bp1 = (byte)(nx * color1.R + fx * color2.R);

                        bp2 = (byte)(nx * color3.R + fx * color4.R);

                        nRed = (byte)(ny * (double)(bp1) + fy * (double)(bp2));

                        bmap.SetPixel(x, y, System.Drawing.Color.FromArgb
                (255, nRed, nGreen, nBlue));
                    }
                }



                bmap = SetGrayscale(bmap);
                bmap = RemoveNoise(bmap);

                return bmap;

        }


//SetGrayscale
  public Bitmap SetGrayscale(Bitmap img)
        {

            Bitmap temp = (Bitmap)img;
            Bitmap bmap = (Bitmap)temp.Clone();
            Color c;
            for (int i = 0; i < bmap.Width; i++)
            {
                for (int j = 0; j < bmap.Height; j++)
                {
                    c = bmap.GetPixel(i, j);
                    byte gray = (byte)(.299 * c.R + .587 * c.G + .114 * c.B);

                    bmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray));
                }
            }
            return (Bitmap)bmap.Clone();

        }
//RemoveNoise
   public Bitmap RemoveNoise(Bitmap bmap)
        {

            for (var x = 0; x < bmap.Width; x++)
            {
                for (var y = 0; y < bmap.Height; y++)
                {
                    var pixel = bmap.GetPixel(x, y);
                    if (pixel.R < 162 && pixel.G < 162 && pixel.B < 162)
                        bmap.SetPixel(x, y, Color.Black);
                    else if (pixel.R > 162 && pixel.G > 162 && pixel.B > 162)
                        bmap.SetPixel(x, y, Color.White);
                }
            }

            return bmap;
        }

EINGABEBILD
EINGABEBILD

AUSGABEBILD AUSGABEBILD


Ja. Wir müssen den erforderlichen Parameter an die Resize-Methode übergeben. Sie führt die Größenänderung, SetGrayscale und RemoveNoise vor und gibt dann das Ausgabebild mit besserer Lesbarkeit zurück.
Sathyaraj Palanisamy

Versuchte diesen Ansatz an einer Reihe von Dateien und verglich ihn mit dem ursprünglichen Ergebnis. In einigen begrenzten Fällen ergibt sich ein besseres Ergebnis, meistens wurde die Qualität des Ausgabetextes leicht verringert. Es sieht also nicht nach einer universellen Lösung aus.
Bryn

Das hat für mich eigentlich ganz gut geklappt. Sicherlich gibt es einen Ausgangspunkt für die Bildvorverarbeitung, der die Menge an Kauderwelsch entfernt, die Sie von Tesseract zurückerhalten.
ses

22

Als Faustregel wende ich normalerweise die folgenden Bildvorverarbeitungstechniken unter Verwendung der OpenCV-Bibliothek an:

  1. Neuskalieren des Bildes (es wird empfohlen, wenn Sie mit Bildern arbeiten, deren DPI weniger als 300 dpi beträgt):

    img = cv2.resize(img, None, fx=1.2, fy=1.2, interpolation=cv2.INTER_CUBIC)
    
  2. Bild in Graustufen konvertieren:

    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
  3. Anwenden von Dilatation und Erosion, um das Rauschen zu entfernen (Sie können abhängig von Ihrem Datensatz mit der Kernelgröße spielen):

    kernel = np.ones((1, 1), np.uint8)
    img = cv2.dilate(img, kernel, iterations=1)
    img = cv2.erode(img, kernel, iterations=1)
    
  4. Anwenden von Unschärfe, die mithilfe einer der folgenden Zeilen erfolgen kann (von denen jede ihre Vor- und Nachteile hat, jedoch wirken sich Medianunschärfe und bilateraler Filter normalerweise besser aus als Gaußsche Unschärfe):

    cv2.threshold(cv2.GaussianBlur(img, (5, 5), 0), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cv2.threshold(cv2.bilateralFilter(img, 5, 75, 75), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cv2.threshold(cv2.medianBlur(img, 3), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
    
    cv2.adaptiveThreshold(cv2.GaussianBlur(img, (5, 5), 0), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    
    cv2.adaptiveThreshold(cv2.bilateralFilter(img, 9, 75, 75), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    
    cv2.adaptiveThreshold(cv2.medianBlur(img, 3), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 31, 2)
    

Ich habe kürzlich eine ziemlich einfache Anleitung zu Tesseract geschrieben, aber sie sollte es Ihnen ermöglichen, Ihr erstes OCR-Skript zu schreiben und einige Hürden zu beseitigen, die ich erlebt habe, als die Dinge weniger klar waren, als ich es mir in der Dokumentation gewünscht hätte.

Falls Sie sie ausprobieren möchten, teile ich hier die Links mit Ihnen:


Warum konvertieren wir das Bild in Graustufen? Genauer gesagt habe ich beim Bilderkennungsprozess gesehen, dass das Bild zuerst in Graustufen konvertiert wird, dann in Sobel-> MSER -> SWT. Könnten Sie es bitte näher erläutern? Ich bin neu im IP-Bereich.
OnePunchMan

Nach meinem Verständnis hängt es vom Algorithmus ab, einige müssen möglicherweise überhaupt nicht konvertieren. Stellen Sie sich Pixel als einige digital gespeicherte Farbwerte vor - im Fall von RGB, Rot, Grün und Blau. Wenn ein Pixel in die S / W-Skala konvertiert wird, muss Ihr Algorithmus nur mit 2 statt mit 3 Dimensionen arbeiten. Dies bringt offensichtliche Geschwindigkeitsvorteile mit sich, wenn Sie Ihren Algorithmus nacheinander auf Pixeln ausführen. Einige sagen auch, dass es einfacher ist, das Rauschen zu entfernen und die Kanten eines Bildes zu erkennen, wenn es in Graustufen konvertiert wird.
Bkaankuguoglu

Danke für die Antwort. Und zu Ihrem Blog könnten Sie bitte einen Artikel über das Erstellen von OCR aus Kratzern unter Verwendung von TESSERACT für nicht-römische Schrift schreiben. Ich habe überall gesucht, alles was richtig verfügbar ist, ist nicht klar.
OnePunchMan

16

Dies ist etwas her, aber es könnte immer noch nützlich sein.

Meine Erfahrung zeigt, dass es manchmal hilfreich ist, die Größe des Bilds im Speicher zu ändern, bevor es an tesseract übergeben wird.

Probieren Sie verschiedene Interpolationsmodi aus. Der Beitrag https://stackoverflow.com/a/4756906/146003 hat mir sehr geholfen.


15

Was mir auf diesem Weg EXTREM HILFREICH war, sind die Quellcodes für das Capture2Text-Projekt. http://sourceforge.net/projects/capture2text/files/Capture2Text/ .

Übrigens: Ein großes Lob an den Autor für das Teilen eines solchen sorgfältigen Algorithmus.

Achten Sie besonders auf die Datei Capture2Text \ SourceCode \ leptonica_util \ leptonica_util.c - das ist die Essenz der Bildvorverarbeitung für dieses Dienstprogramm.

Wenn Sie die Binärdateien ausführen, können Sie die Bildtransformation vor / nach dem Vorgang im Ordner Capture2Text \ Output \ überprüfen.

Die von PS erwähnte Lösung verwendet Tesseract für OCR und Leptonica für die Vorverarbeitung.


1
Vielen Dank für das Capture2Text-Tool. Es löst perfekt alle OCR-Probleme in meinem Projekt!
Lê Quang Duy

12

Java-Version für Sathyarajs Code oben:

// Resize
public Bitmap resize(Bitmap img, int newWidth, int newHeight) {
    Bitmap bmap = img.copy(img.getConfig(), true);

    double nWidthFactor = (double) img.getWidth() / (double) newWidth;
    double nHeightFactor = (double) img.getHeight() / (double) newHeight;

    double fx, fy, nx, ny;
    int cx, cy, fr_x, fr_y;
    int color1;
    int color2;
    int color3;
    int color4;
    byte nRed, nGreen, nBlue;

    byte bp1, bp2;

    for (int x = 0; x < bmap.getWidth(); ++x) {
        for (int y = 0; y < bmap.getHeight(); ++y) {

            fr_x = (int) Math.floor(x * nWidthFactor);
            fr_y = (int) Math.floor(y * nHeightFactor);
            cx = fr_x + 1;
            if (cx >= img.getWidth())
                cx = fr_x;
            cy = fr_y + 1;
            if (cy >= img.getHeight())
                cy = fr_y;
            fx = x * nWidthFactor - fr_x;
            fy = y * nHeightFactor - fr_y;
            nx = 1.0 - fx;
            ny = 1.0 - fy;

            color1 = img.getPixel(fr_x, fr_y);
            color2 = img.getPixel(cx, fr_y);
            color3 = img.getPixel(fr_x, cy);
            color4 = img.getPixel(cx, cy);

            // Blue
            bp1 = (byte) (nx * Color.blue(color1) + fx * Color.blue(color2));
            bp2 = (byte) (nx * Color.blue(color3) + fx * Color.blue(color4));
            nBlue = (byte) (ny * (double) (bp1) + fy * (double) (bp2));

            // Green
            bp1 = (byte) (nx * Color.green(color1) + fx * Color.green(color2));
            bp2 = (byte) (nx * Color.green(color3) + fx * Color.green(color4));
            nGreen = (byte) (ny * (double) (bp1) + fy * (double) (bp2));

            // Red
            bp1 = (byte) (nx * Color.red(color1) + fx * Color.red(color2));
            bp2 = (byte) (nx * Color.red(color3) + fx * Color.red(color4));
            nRed = (byte) (ny * (double) (bp1) + fy * (double) (bp2));

            bmap.setPixel(x, y, Color.argb(255, nRed, nGreen, nBlue));
        }
    }

    bmap = setGrayscale(bmap);
    bmap = removeNoise(bmap);

    return bmap;
}

// SetGrayscale
private Bitmap setGrayscale(Bitmap img) {
    Bitmap bmap = img.copy(img.getConfig(), true);
    int c;
    for (int i = 0; i < bmap.getWidth(); i++) {
        for (int j = 0; j < bmap.getHeight(); j++) {
            c = bmap.getPixel(i, j);
            byte gray = (byte) (.299 * Color.red(c) + .587 * Color.green(c)
                    + .114 * Color.blue(c));

            bmap.setPixel(i, j, Color.argb(255, gray, gray, gray));
        }
    }
    return bmap;
}

// RemoveNoise
private Bitmap removeNoise(Bitmap bmap) {
    for (int x = 0; x < bmap.getWidth(); x++) {
        for (int y = 0; y < bmap.getHeight(); y++) {
            int pixel = bmap.getPixel(x, y);
            if (Color.red(pixel) < 162 && Color.green(pixel) < 162 && Color.blue(pixel) < 162) {
                bmap.setPixel(x, y, Color.BLACK);
            }
        }
    }
    for (int x = 0; x < bmap.getWidth(); x++) {
        for (int y = 0; y < bmap.getHeight(); y++) {
            int pixel = bmap.getPixel(x, y);
            if (Color.red(pixel) > 162 && Color.green(pixel) > 162 && Color.blue(pixel) > 162) {
                bmap.setPixel(x, y, Color.WHITE);
            }
        }
    }
    return bmap;
}

Was ist deine Klasse für Bitmap? Bitmap wird in Java nicht gefunden (nativ in Android).
Wir sind Borg

Diese Methode durchläuft eine Ausnahme: Auslöser: java.lang.IllegalArgumentException: y muss <bitmap.height () sein
Nativ

9

Die Tesseract-Dokumentation enthält einige gute Details zur Verbesserung der OCR-Qualität durch Bildverarbeitungsschritte.

Bis zu einem gewissen Grad wendet Tesseract sie automatisch an. Es ist auch möglich, Tesseract anzuweisen, ein Zwischenbild zur Überprüfung zu schreiben, dh zu überprüfen, wie gut die interne Bildverarbeitung funktioniert (Suche tessedit_write_imagesin der obigen Referenz).

Noch wichtiger ist, dass das neue neuronale Netzwerksystem in Tesseract 4 viel bessere OCR-Ergebnisse liefert - im Allgemeinen und insbesondere für Bilder mit etwas Rauschen. Es ist aktiviert mit --oem 1zB wie in:

$ tesseract --oem 1 -l deu page.png result pdf

(In diesem Beispiel wird die deutsche Sprache ausgewählt.)

Daher ist es sinnvoll, zunächst zu testen, wie weit Sie mit dem neuen Tesseract LSTM-Modus kommen, bevor Sie einige benutzerdefinierte Bildverarbeitungsschritte vor der Verarbeitung anwenden.


6

Adaptive Schwellenwerte sind wichtig, wenn die Beleuchtung im gesamten Bild ungleichmäßig ist. Meine Vorverarbeitung mit GraphicsMagic wird in diesem Beitrag erwähnt: https://groups.google.com/forum/#!topic/tesseract-ocr/jONGSChLRv4

GraphicsMagic hat auch die -lat-Funktion für Linear Time Adaptive Threshold, die ich bald ausprobieren werde.

Eine andere Methode zur Schwellenwertbildung mit OpenCV wird hier beschrieben: http://docs.opencv.org/trunk/doc/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html


2
Die OpenCV-Verbindung wird geändert. In der OpenCV-Dokumentation ist es OpenCV-Python-Tutorials> Bildverarbeitung in OpenCV>
Bildschwelle

2

Ich habe dies getan, um gute Ergebnisse mit einem Bild zu erzielen, das keinen sehr kleinen Text enthält.

  1. Wenden Sie Unschärfe auf das Originalbild an.
  2. Wenden Sie den adaptiven Schwellenwert an.
  3. Schärfeeffekt anwenden.

Und wenn immer noch keine guten Ergebnisse erzielt werden, skalieren Sie das Bild auf 150% oder 200%.


2

Das Lesen von Text aus Bilddokumenten mit einer beliebigen OCR-Engine hat viele Probleme, um eine gute Genauigkeit zu erzielen. Es gibt keine feste Lösung für alle Fälle, aber hier sind einige Dinge, die berücksichtigt werden sollten, um die OCR-Ergebnisse zu verbessern.

1) Vorhandensein von Rauschen aufgrund schlechter Bildqualität / unerwünschter Elemente / Blobs im Hintergrundbereich. Dies erfordert einige Vorverarbeitungsvorgänge wie die Rauschentfernung, die leicht unter Verwendung eines Gaußschen Filters oder normaler Medianfiltermethoden durchgeführt werden können. Diese sind auch in OpenCV verfügbar.

2) Falsche Ausrichtung des Bildes: Aufgrund der falschen Ausrichtung kann die OCR-Engine die Linien und Wörter im Bild nicht richtig segmentieren, was die schlechteste Genauigkeit ergibt.

3) Vorhandensein von Zeilen: Während der Wort- oder Zeilensegmentierung versucht die OCR-Engine manchmal auch, die Wörter und Zeilen zusammenzuführen und so falschen Inhalt zu verarbeiten und damit falsche Ergebnisse zu erzielen. Es gibt auch andere Probleme, aber dies sind die grundlegenden.

Diese Post- OCR-Anwendung ist ein Beispielfall, in dem einige Bildvorverarbeitungen und Nachverarbeitungen für OCR-Ergebnisse angewendet werden können, um eine bessere OCR-Genauigkeit zu erzielen.


1

Die Texterkennung hängt von einer Vielzahl von Faktoren ab, um eine qualitativ hochwertige Ausgabe zu erzielen. Die OCR-Ausgabe hängt stark von der Qualität des Eingabebildes ab. Aus diesem Grund bietet jede OCR-Engine Richtlinien zur Qualität des Eingabebilds und seiner Größe. Diese Richtlinien helfen der OCR-Engine, genaue Ergebnisse zu erzielen.

Ich habe einen ausführlichen Artikel über die Bildverarbeitung in Python geschrieben. Bitte folgen Sie dem Link unten für weitere Erklärungen. Fügte auch den Python-Quellcode hinzu, um diesen Prozess zu implementieren.

Bitte schreiben Sie einen Kommentar, wenn Sie einen Vorschlag oder eine bessere Idee zu diesem Thema haben, um es zu verbessern.

https://medium.com/cashify-engineering/improve-accuracy-of-ocr-using-image-preprocessing-8df29ec3a033


2
Bitte fügen Sie hier eine Antwort als Zusammenfassung Ihres Blogs hinzu. Selbst wenn der Link tot ist, wird die Antwort nicht unbrauchbar.
Nithin

0

Sie können Rauschunterdrückung durchführen und dann Schwellenwerte anwenden. Sie können jedoch mit der Konfiguration der OCR herumspielen, indem Sie die Werte --psm und --oem ändern

versuchen Sie: --psm 5 --oem 2

Weitere Informationen finden Sie auch unter folgendem Link

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.