[Python] Holen Sie sich die Zahlen im Diagramm mit OCR

Zweck

Ich möchte die Differenzzahl aus dem Diagramm der Pachislot-Datenseite berechnen.

Zu diesem Zeitpunkt wird die Anzahl der auf der OCR angezeigten Blätter erfasst, da die Anzahl der im Diagramm angezeigten Blätter erforderlich war.

20200713_p-bbnippori_126.png

Ein solches Diagrammbild.

Was Sie erhalten möchten, ist die oben links angezeigte Nummer (2410 im Fall dieses Bildes)

Was vorzubereiten?

・ Tesseract (4.0 oder höher) ・ PyOCR

Die Installationsmethode usw. entfällt. Ein Referenzlink befindet sich am Ende der Seite. Bitte verwenden Sie diesen.

Versuchen Sie es mit OCR

20200713_p-bbnippori_126.png

Lesen Sie dieses Diagramm vorerst so, wie es ist.

from PIL import Image
import pyocr
import pyocr.builders
import sys

file_path = 'Dateipfad'
#Laden von Werkzeugen
tools = pyocr.get_available_tools()
#Wenn Sie das Werkzeug nicht finden können
if len(tools) == 0:
    print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
    sys.exit(1)
tool = tools[0]
#Bild wird geladen
img_org = Image.open(file_path)
# OCR
max_medals = tool.image_to_string(img_org, lang='jpn', builder=pyocr.builders.DigitBuilder(tesseract_layout=6))
print(f'max_medals:{max_medals}')

Ausführungsergebnis


-

Ich konnte keine Zahlen bekommen.

Nachdem ich verschiedene Dinge untersucht habe, scheint es genauer zu sein, numerische OCR mit einem englischen Datensatz durchzuführen, daher habe ich die Spracheinstellung auf Englisch geändert.

Ändern Sie die Spracheinstellung in Englisch

from PIL import Image
import pyocr
import pyocr.builders
import sys

file_path = 'Dateipfad'
#Laden von Werkzeugen
tools = pyocr.get_available_tools()
#Wenn Sie das Werkzeug nicht finden können
if len(tools) == 0:
    print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
    sys.exit(1)
tool = tools[0]
#Bild wird geladen
img_org = Image.open(file_path)
# OCR
max_medals = tool.image_to_string(img_org, lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=6))
print(f'max_medals:{max_medals}')

Ausführungsergebnis


2410 1300160019.00

Diesmal konnte ich einige der angezeigten Zahlen erhalten.

Da ich jedoch die unnötigen Teile gelesen habe, schreibe ich sie neu, sodass nur der Teil, den ich lesen möchte, ausgeschnitten und dann verarbeitet wird.

OCR nach Ausschneiden des Lesepunktes

from PIL import Image
import pyocr
import pyocr.builders
import sys

file_path = 'Dateipfad'
#Laden von Werkzeugen
tools = pyocr.get_available_tools()
#Wenn Sie das Werkzeug nicht finden können
if len(tools) == 0:
    print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
    sys.exit(1)
tool = tools[0]
#Bild wird geladen
img_org = Image.open(file_path)
#Schneiden Sie den Teil mit der Notation aus
max_medals_img = img_org.crop((0, 0, 45, 15))
# OCR
max_medals = tool.image_to_string(max_medals_img , lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=6))
print(f'max_medals:{max_medals}')

Ausführungsergebnis


max_medals:2410

Es ging gut!

Upgrade-Genauigkeit

Da es mit dem vorherigen Code gut funktioniert hat, habe ich die Anzahl der zu lesenden und erneut versuchten Grafikbilder erhöht.

from PIL import Image
import pyocr
import pyocr.builders
import sys
from glob import glob

file_path = 'Dateispeicherverzeichnis'
#Erstellen Sie eine Dateiliste zum Lesen
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
    #Laden von Werkzeugen
    tools = pyocr.get_available_tools()
    #Wenn Sie das Werkzeug nicht finden können
    if len(tools) == 0:
        print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
        sys.exit(1)
    tool = tools[0]
    #Bild wird geladen
    img_org = Image.open(file_path)
    #Schneiden Sie den Teil mit der Notation aus
    max_medals_img = img_org.crop((0, 0, 45, 15))
    # OCR
    max_medals = tool.image_to_string(max_medals_img, lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=6))
    print(f'max_medals:{max_medals}')

Ausführungsergebnis


max_medals:2410
max_medals:
max_medals:490
max_medals:2717
max_medals:689
max_medals:504
max_medals:1013
max_medals:
max_medals:862
max_medals:979
max_medals:835
max_medals:1683
max_medals:1587
max_medals:1010
max_medals:7
max_medals:1586
max_medals:1653
max_medals:413
max_medals:1167
max_medals:527

Einige Bilder wurden nicht richtig gelesen.

Ich habe OCR bereits mit einem anderen Formatbild versucht und zu diesem Zeitpunkt habe ich keinen Fehler erhalten, aber das Format zu diesem Zeitpunkt ist

"Hintergrundfarbe: weiß, Textfarbe: schwarz"

Da es sich um ein Bild des Formats handelte, habe ich versucht, die Hintergrundfarbe und die Textfarbe umzukehren.

Hintergrundfarbe und Textfarbe invertieren

from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob

file_path = 'Dateispeicherverzeichnis'
#Erstellen Sie eine Dateiliste zum Lesen
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
    #Laden von Werkzeugen
    tools = pyocr.get_available_tools()
    #Wenn Sie das Werkzeug nicht finden können
    if len(tools) == 0:
        print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
        sys.exit(1)
    tool = tools[0]
    #Bild wird geladen
    img_org = Image.open(file_path)
    #Schneiden Sie den Teil mit der Notation aus
    max_medals_img = img_org.crop((0, 0, 45, 15))
    #Hintergrundfarbe und Textfarbe umkehren (von weißem Text in schwarzen Text konvertieren)
    max_medals_img = ImageOps.invert(max_medals_img.convert('RGB'))
    # OCR
    max_medals = tool.image_to_string(max_medals_img, lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=6))
    print(f'max_medals:{max_medals}')

Ausführungsergebnis


max_medals:2410
max_medals:440
max_medals:490
max_medals:2717
max_medals:689
max_medals:504
max_medals:1013
max_medals:791
max_medals:862
max_medals:979
max_medals:835
max_medals:1683
max_medals:1587
max_medals:1010
max_medals:1132
max_medals:1586
max_medals:1653
max_medals:413
max_medals:1167
max_medals:527

Bilder, die nicht normal erkannt werden konnten, wurden ebenfalls normal erkannt.

Ich habe versucht, die Anzahl der Bildlesebeispiele mit diesem Code zu erhöhen ...

Ausführungsergebnis


max_medals:1908.
max_medals:
max_medals:1000-
max_medals:10

Es gibt immer noch seltene Fälle, in denen Zeichen, die nicht auf diese Weise geschrieben wurden, eingemischt werden, die Anzahl der Ziffern falsch ist oder die Zahlen überhaupt nicht erkannt werden können.

(7 von 10.000)

Der OCR-Modus wurde geändert, um die Genauigkeit weiter zu verbessern.

Ändern Sie den Modus von 6 auf 8 (Modus, in dem Bilder als Wörter betrachtet werden)

from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob

file_path = 'Dateispeicherverzeichnis'
#Erstellen Sie eine Dateiliste zum Lesen
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
    #Laden von Werkzeugen
    tools = pyocr.get_available_tools()
    #Wenn Sie das Werkzeug nicht finden können
    if len(tools) == 0:
        print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
        sys.exit(1)
    tool = tools[0]
    #Bild wird geladen
    img_org = Image.open(file_path)
    #Schneiden Sie den Teil mit der Notation aus
    max_medals_img = img_org.crop((0, 0, 45, 15))
    #Hintergrundfarbe und Textfarbe umkehren (von weißem Text in schwarzen Text konvertieren)
    max_medals_img = ImageOps.invert(max_medals_img.convert('RGB'))
    # OCR
    max_medals = tool.image_to_string(max_medals_img, lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=8))
    print(f'max_medals:{max_medals}')

In einen Modus geändert, in dem ein Bild selbst als Wort betrachtet wird. (Dieser Modus sollte optimal sein, da die OCR ausgeführt wird, nachdem nur der Teil mit der Nummernnotation geschnitten wurde.) Dieser Modus ist genauer.

(Reduziert auf ungefähr 4 von 10.000)

Da es jedoch Fälle gab, in denen es nicht normal erkannt wurde, habe ich einen Code hinzugefügt, um vorerst andere Zeichen als numerische Werte auszuschließen.

Nicht numerische Zeichen ausschließen

import re
from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob

file_path = 'Dateispeicherverzeichnis'
#Erstellen Sie eine Dateiliste zum Lesen
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
    #Laden von Werkzeugen
    tools = pyocr.get_available_tools()
    #Wenn Sie das Werkzeug nicht finden können
    if len(tools) == 0:
        print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
        sys.exit(1)
    tool = tools[0]
    #Bild wird geladen
    img_org = Image.open(file_path)
    #Schneiden Sie den Teil mit der Notation aus
    max_medals_img = img_org.crop((0, 0, 45, 15))
    #Hintergrundfarbe und Textfarbe umkehren (von weißem Text in schwarzen Text konvertieren)
    max_medals_img = ImageOps.invert(max_medals_img.convert('RGB'))
    # OCR
    max_medals = tool.image_to_string(max_medals_img, lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=8))
    #Entfernen Sie nicht numerische Zeichen
    max_medals = re.sub(r'\D', '', max_medals)
    print(f'max_medals:{max_medals}')

Dies vermeidet den Fall, dass andere Zeichen als nicht markierte Zahlen wie "-" und "." Eingemischt werden.

In seltenen Fällen konnte der numerische Wert selbst jedoch nicht erkannt werden oder die Anzahl der Ziffern war falsch.

Ich frage mich, was ich tun und verschiedene Verbesserungsmaßnahmen entwickeln soll

Holen Sie sich die Nummernnotation sowohl oben links als auch unten links im Bild ↓ Vergleichen Sie beide ↓ Adoptiere eine Person, die normal zu sein scheint

Ich habe über einige logische Muster nachgedacht, aber der Code war lang und kompliziert, deshalb werde ich hier ein wenig darüber nachdenken.

** "Erstens müssen Sie keinen störenden Code schreiben, wenn Sie die Erkennungsgenauigkeit in OCR verbessern können." **

Ich kam auf die Idee, dass es ganz natürlich ist, und versuchte, die Ausschnittgröße der OCR-Vorverarbeitung auf verschiedene Arten zu ändern.

Endgültiger Code

import re
from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob

file_path = 'Dateispeicherverzeichnis'
#Erstellen Sie eine Dateiliste zum Lesen
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
    #Laden von Werkzeugen
    tools = pyocr.get_available_tools()
    #Wenn Sie das Werkzeug nicht finden können
    if len(tools) == 0:
        print('Ich kann Pyocr nicht finden. Bitte installieren Sie pyocr.')
        sys.exit(1)
    tool = tools[0]
    #Bild wird geladen
    img_org = Image.open(file_path)
    #Schneiden Sie den Teil mit der Notation aus
    max_medals_img = img_org.crop((0, 0, 44, 14))
    #Hintergrundfarbe und Textfarbe umkehren (von weißem Text in schwarzen Text konvertieren)
    max_medals_img = ImageOps.invert(max_medals_img.convert('RGB'))
    # OCR
    max_medals = tool.image_to_string(max_medals_img, lang='eng', builder=pyocr.builders.DigitBuilder(tesseract_layout=8))
    #Entfernen Sie nicht numerische Zeichen
    max_medals = re.sub(r'\D', '', max_medals)
    print(f'max_medals:{max_medals}')

Nachdem ich verschiedene Größen ausprobiert hatte, wurde die Erkennungsrate des Grafikbildes, das ich mit diesem Code hatte, 100%!

Infolgedessen war es besser, die beste Methode für die Schnittgröße zu finden, als über Logik nachzudenken (lacht).

Fazit

Wenn Sie die Zeichen nicht gut erkennen können

** Zweifle zuerst an dem Bild> Überprüfe die Einstellungen usw.> Passe es an, indem du eine weitere Logik hinzufügst **

Ich denke, es wird schwieriger sein, süchtig zu werden, wenn Sie in dieser Reihenfolge arbeiten.

Dieses Mal ist es äußerst genau, OCR, obwohl es nur numerische Werte erkennt.

Referenzlink

Zeichenerkennung mit Python und Tesseract OCR So führen Sie OCR in Python aus

Recommended Posts

[Python] Holen Sie sich die Zahlen im Diagramm mit OCR
[Python] Holen Sie sich die Dateien mit Python in den Ordner
Bestimmen Sie die Zahlen in dem mit der Webkamera aufgenommenen Bild
Tweet mit Bild in Python
Konvertieren Sie das Bild in .zip mit Python in PDF
Mit Python psycopg2 erhalten Sie Ergebnisse im Diktatformat
Testen mit Zufallszahlen in Python
Holen Sie sich den Desktop-Pfad in Python
Holen Sie sich das Wetter mit Python-Anfragen
Holen Sie sich das Wetter mit Python-Anfragen 2
Holen Sie sich den Skriptpfad in Python
Holen Sie sich den Desktop-Pfad in Python
Holen Sie sich den Hostnamen in Python
Beginnen Sie mit Python mit Blender
Holen Sie sich mit Python zusätzliche Daten zu LDAP
[Python] Legen Sie den Diagrammbereich mit matplotlib fest
[Python] Ruft den Variablennamen mit str ab
Zeigen Sie Python 3 im Browser mit MAMP an
Beginnen wir mit TopCoder in Python (Version 2020)
Verarbeiten Sie Bilder in Python ganz einfach mit Pillow
Ruft die EDINET-Codeliste in Python ab
Lesen von Zeichen in Bildern mit Python OCR
So ermitteln Sie mit Python den Unterschied zwischen Datum und Uhrzeit in Sekunden
Abrufen und Konvertieren der aktuellen Zeit in der lokalen Systemzeitzone mit Python
Lesen Sie das Diagrammbild mit OpenCV und ermitteln Sie die Koordinaten des Endpunkts des Diagramms
Ich habe versucht, das Bild mit Python + OpenCV zu "glätten"
Holen Sie sich das Wetter in Osaka über Web-API (Python)
Ich habe versucht, das Bild mit Python + OpenCV zu "differenzieren"
Holen Sie sich den Aufrufer einer Funktion in Python
Was ist im Docker Python-Image pfeifend?
[Automatisierung] Extrahieren Sie die Tabelle als PDF mit Python
Holen Sie sich die Bild-URL mithilfe der Flickr-API in Python
Ruft den Fenstertitel des X-Fenstersystems in Python ab
Erkennen Sie Ordner mit demselben Bild in ImageHash
Ich habe versucht, das Bild mit Python + OpenCV zu "binarisieren"
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
So erhalten Sie die Dateien im Ordner [Python]
Holen Sie sich die Datei, Funktion, Zeilennummer in Python ausgeführt
Diagrammzeichnung mit Python
Bildformat in Python
Holen Sie sich Datum in Python
Bildverarbeitung mit Python
Holen Sie sich ein Date mit Python
Primzahl in Python
Zeichnen Sie ein Diagramm mit Python
Erhalten Sie mit Python Informationen zu den 100 einflussreichsten technischen Twitter-Nutzern der Welt.
Holen Sie sich mit Python den Aktienkurs eines japanischen Unternehmens und erstellen Sie eine Grafik
So erhalten Sie mit Python eine Liste der Dateien im selben Verzeichnis
So ermitteln Sie die Anzahl der Stellen in Python
[Python] Ruft die Liste der im Modul definierten Klassen ab
Holen Sie sich die Standardausgabe in Echtzeit mit dem Python-Unterprozess
Crawlen Sie die im Twitter-Tweet enthaltene URL mit Python
Schreiben Sie mit OpenCV-Python Zeichen in die Kartenillustration
Ermitteln Sie die Größe (Anzahl der Elemente) von Union Find in Python
Rufen Sie den im Pulldown-Menü Selenium Python VBA ausgewählten Wert ab
Holen Sie sich mit Python den Betriebsstatus von JR West
Rufen Sie die URL des HTTP-Umleitungsziels in Python ab