Je veux calculer le nombre de différence à partir de l'image graphique du site de données pachislot.
À ce moment-là, étant donné que le nombre de feuilles indiqué sur l'image graphique était requis, le nombre de feuilles affiché sur l'OCR est acquis.
Une telle image graphique.
Ce que vous voulez obtenir est le nombre indiqué en haut à gauche (2410 dans le cas de cette image)
・ Tesseract (4.0 ou version ultérieure) ・ PyOCR
La méthode d'installation, etc. est omise. Un lien de référence est affiché au bas de la page, veuillez donc l'utiliser.
Pour le moment, lisez cette image graphique telle quelle.
from PIL import Image
import pyocr
import pyocr.builders
import sys
file_path = 'Chemin du fichier'
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
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}')
Résultat d'exécution
-
Je n'ai pas pu obtenir de chiffres.
Après avoir étudié diverses choses, il semble qu'il soit plus précis de faire de l'OCR numérique avec un ensemble de données anglais, j'ai donc changé le paramètre de langue en anglais.
from PIL import Image
import pyocr
import pyocr.builders
import sys
file_path = 'Chemin du fichier'
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
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}')
Résultat d'exécution
2410 1300160019.00
Cette fois, j'ai pu obtenir certains des chiffres indiqués.
Cependant, comme j'ai lu les parties inutiles, je la réécris pour que seule la partie que je souhaite lire soit découpée puis traitée.
from PIL import Image
import pyocr
import pyocr.builders
import sys
file_path = 'Chemin du fichier'
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
img_org = Image.open(file_path)
#Découpez la partie de notation numérique
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}')
Résultat d'exécution
max_medals:2410
Ça s'est bien passé!
Comme cela fonctionnait bien avec le code précédent, j'ai augmenté le nombre d'images graphiques à lire et à réessayer.
from PIL import Image
import pyocr
import pyocr.builders
import sys
from glob import glob
file_path = 'Répertoire de stockage de fichiers'
#Créer une liste de fichiers à lire
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
img_org = Image.open(file_path)
#Découpez la partie de notation numérique
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}')
Résultat d'exécution
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
Certaines images n'ont pas été lues correctement.
J'ai déjà essayé l'OCR avec un autre format d'image auparavant, et à ce moment-là je n'ai eu aucune erreur, mais le format à ce moment
"Couleur d'arrière-plan: blanc, couleur du texte: noir"
Puisqu'il s'agissait d'une image du format, j'ai essayé d'inverser la couleur d'arrière-plan et la couleur du texte.
from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob
file_path = 'Répertoire de stockage de fichiers'
#Créer une liste de fichiers à lire
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
img_org = Image.open(file_path)
#Découpez la partie de notation numérique
max_medals_img = img_org.crop((0, 0, 45, 15))
#Inverser la couleur d'arrière-plan et la couleur du texte (convertir du texte blanc en texte noir)
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}')
Résultat d'exécution
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
Les images qui ne pouvaient pas être reconnues normalement étaient également reconnues normalement.
J'ai essayé d'augmenter le nombre d'échantillons de lecture d'image avec ce code ...
Résultat d'exécution
max_medals:1908.
max_medals:
max_medals:1000-
max_medals:10
Il existe encore de rares cas où des caractères qui ne sont pas écrits de cette manière sont mélangés, le nombre de chiffres est incorrect ou les nombres ne peuvent pas être reconnus en premier lieu.
(7 sur 10000)
Changement du mode OCR pour améliorer encore la précision.
from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob
file_path = 'Répertoire de stockage de fichiers'
#Créer une liste de fichiers à lire
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
img_org = Image.open(file_path)
#Découpez la partie de notation numérique
max_medals_img = img_org.crop((0, 0, 45, 15))
#Inverser la couleur d'arrière-plan et la couleur du texte (convertir du texte blanc en texte noir)
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}')
Passé à un mode dans lequel une image elle-même est considérée comme un mot. (Ce mode doit être optimal car l'OCR est effectué après avoir coupé uniquement la partie de notation numérique) Ce mode est plus précis.
(Réduit à environ 4 sur 10000)
Cependant, comme il y avait des cas où il n'était pas reconnu normalement, j'ai ajouté un code pour exclure les caractères autres que les valeurs numériques pour le moment.
import re
from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob
file_path = 'Répertoire de stockage de fichiers'
#Créer une liste de fichiers à lire
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
img_org = Image.open(file_path)
#Découpez la partie de notation numérique
max_medals_img = img_org.crop((0, 0, 45, 15))
#Inverser la couleur d'arrière-plan et la couleur du texte (convertir du texte blanc en texte noir)
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))
#Supprimer les caractères non numériques
max_medals = re.sub(r'\D', '', max_medals)
print(f'max_medals:{max_medals}')
Cela évite le cas où des caractères autres que des nombres non marqués tels que "-" et "." Sont mélangés.
Cependant, dans de rares cas, la valeur numérique elle-même n'a pas pu être reconnue ou le nombre de chiffres était incorrect.
Je me demande quoi faire et je conçois diverses mesures d'amélioration
Obtenez la notation numérique en haut à gauche et en bas à gauche de l'image ↓ Comparez les deux ↓ Adoptez une personne qui semble normale
J'ai pensé à quelques schémas de logique, mais le code était long et compliqué, donc je vais revenir un peu ici.
** "En premier lieu, si vous pouvez améliorer la précision de la reconnaissance dans l'OCR, vous n'avez pas à écrire de code gênant." **
J'ai eu l'idée que c'était assez naturel et j'ai essayé de changer la taille de la découpe de notation numérique du prétraitement OCR de différentes manières.
import re
from PIL import Image, ImageOps
import pyocr
import pyocr.builders
import sys
from glob import glob
file_path = 'Répertoire de stockage de fichiers'
#Créer une liste de fichiers à lire
file_list = [file for file in glob(f'{file_path}*.png')]
for file_path in file_list:
#Chargement des outils
tools = pyocr.get_available_tools()
#Si vous ne trouvez pas l'outil
if len(tools) == 0:
print('Je ne trouve pas pyocr. Veuillez installer pyocr.')
sys.exit(1)
tool = tools[0]
#Chargement d'image
img_org = Image.open(file_path)
#Découpez la partie de notation numérique
max_medals_img = img_org.crop((0, 0, 44, 14))
#Inverser la couleur d'arrière-plan et la couleur du texte (convertir du texte blanc en texte noir)
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))
#Supprimer les caractères non numériques
max_medals = re.sub(r'\D', '', max_medals)
print(f'max_medals:{max_medals}')
Après avoir essayé différentes tailles, le taux de reconnaissance de l'image graphique que j'avais avec ce code est devenu 100%!
En conséquence, il valait mieux trouver la meilleure pratique de taille de coupe que de penser à la logique (rires)
Si vous ne reconnaissez pas bien les personnages
** Douter de l'image en premier lieu> Vérifiez les paramètres, etc.> Ajustez en ajoutant une autre logique **
Je pense qu'il sera plus difficile de devenir accro si vous travaillez dans cet ordre.
Cette fois, même s'il ne reconnaît que des valeurs numériques, il est extrêmement précis, l'OCR.
Reconnaissance de caractères avec Python et Tesseract OCR Comment exécuter l'OCR en Python
Recommended Posts