[PYTHON] J'ai essayé de créer une application OCR avec PySimpleGUI

■ Contexte

Je me suis demandé si je pouvais facilement créer une application OCR qui démarre sur le bureau, alors je l'ai créée.

■ Environnement

・ MacOS Catalina 10.15.4 ・ Code Visual Studio ・ Python3.8.1

■ Installation de la bibliothèque

    1. PysimpleGUI (Créer une interface graphique)
pip install pysimplegui

2. Tesseract OCR(OCR)

brew install tesseract
  1. pyocr (wrapper d'outil OCR pour Python)
sudo pip3 install pyocr
  1. oreiller (image de chargement)
sudo pip3 install pillow

● Quelles sont ces bibliothèques? Y compris cela, j'ai beaucoup fait référence aux sites suivants pour l'OCR (merci). Essayez l'OCR simple avec Tesseract + PyOCR

● Cela peut être plus facile à comprendre pour les utilisateurs Windows. [Python] Comment transcrire une image et la convertir en texte (tesseract-OCR, pyocr)

Voyons maintenant comment écrire le code pour lire les caractères de l'image (l'importation de la bibliothèque est incluse dans le code source final, donc je l'omettrai ici).

def scan_file_to_str(file_path, langage):
   """read_file_to_str

Générer une chaîne à partir d'un fichier image

        Args:
            file_path(str):Chemin du fichier à lire
            langage(str): 'jpn'Ou'eng'

        Returns:
Lire la chaîne de caractères
   """
   tools = pyocr.get_available_tools()
   if len(tools) == 0:
      print("No OCR tool found")
      sys.exit(1)

   tool = tools[0]

   text = tool.image_to_string(
      #Ouvrez le fichier envoyé en argument
      Image.open(file_path),
      #Spécifiez la langue envoyée comme argument('jpn'Ou'eng')
      lang=langage,
      builder=pyocr.builders.TextBuilder(tesseract_layout=6)
   )
   #Renvoie enfin la chaîne de caractères lue depuis l'image
   return text

Il est vraiment surprenant que vous puissiez lire une chaîne de caractères à partir d'une image en seulement 15 lignes. Je ai été impressionné.

Ensuite, je mettrai ceci sur l'interface graphique. Je pense que tkinter est célèbre en ce qui concerne l'interface graphique Python. J'écrivais du code en utilisant tkinter au début, mais lorsque je faisais la recherche, je suis tombé sur l'article suivant.

[Si vous utilisez Tkinter, essayez d'utiliser PySimpleGUI](https://qiita.com/dario_okazaki/items/656de21cab5c81cabe59#exe%E5%8C%96%E3%81%AB%E3%81%A4 % E3% 81% 84% E3% 81% A6)

J'ai également été impressionné par le fait que l'interface graphique pouvait être implémentée avec un code simple, j'ai donc décidé de l'utiliser.

Voici le code de la partie GUI.

#Définir le thème(Il existe de nombreux thèmes)
sg.theme('Light Grey1')

#Où et quoi placer(Je pense que ce sera plus facile à assembler si vous savez qu'il est organisé en unités de lignes.)
layout = [
    #La première ligne(Text:Mettez le texte)
    [sg.Text('Fichier à lire(Plusieurs sélections possibles)', font=('IPA gothique', 16))],

    #2e ligne(InputText:Zone de texte, FilesBrowse:Boîte de dialogue de fichier)
    [sg.InputText(font=('IPA gothique', 14), size=(70, 10),), sg.FilesBrowse('Sélectionnez les fichiers', key='-FILES-'),],

    #3e ligne(Text:texte, Radio:Bouton radio x 2)
    [sg.Text('Langue à lire', font=('IPA gothique', 16)), 
    sg.Radio('Japonais', 1, key='-jpn-', font=('IPA gothique', 10)),
    sg.Radio('Anglais', 1, key='-eng-', font=('IPA gothique', 10))],

    #4ème ligne(Button:bouton)
    [sg.Button('Lire l'exécution'),],

    #5ème ligne(MLine:100 colonnes x 30 lignes textarea)
    [sg.MLine(font=('IPA gothique', 14), size=(100,30), key='-OUTPUT-'),]
]

#Obtenir la fenêtre(L'argument de Window est "Title, Layout")
window = sg.Window('OCR facile', layout)

#Liste pour mettre le fichier lu
files = []

#Maintenant, tournez la boucle infinie et attendez les événements tels que les clics de bouton.
while True:
    event, values = window.read()
    #Aucun est le bouton "✕" dans la fenêtre. Lorsque vous appuyez sur ce bouton, il sort de la boucle et ferme la fenêtre.
    if event == None:
        break
    
    # 'Lire l'exécution'Lorsque le bouton est enfoncé
    if event == 'Lire l'exécution':
        # key='-FILES-'La valeur de InputText spécifiée dans';'Obtenez une liste de noms de fichiers séparés par
        files.extend(values['-FILES-'].split(';'))
        #Valeurs des boutons radio['-jpn-']Alors la langue est'jpn',Autrement'eng'
        language = 'jpn' if values['-jpn-'] else 'eng'
        text = ''
        #Boucle par le nombre de fichiers
        for i in range(len(files)):
            if not i == 0:
                #Il y a un délimiteur pour chaque fichier
                text += '================================================================================================\n'
                #Le scan défini précédemment ici_file_to_Recevoir la chaîne de lecture avec la méthode str
                text += scan_file_to_str(files[i], language)
         
                if language == 'jpn':
                #Dans le cas des chaînes de caractères japonais, il y avait beaucoup d'espace supplémentaire, donc je l'ai supprimé.
                text = text.replace(' ', '')
                #Laissez deux lignes à part la chaîne dans le fichier suivant
                text += '\n\n'
        #Lire les données(=text)Clé='-OUTPUT-'Affichage sur la MLine spécifiée dans
        window.FindElement('-OUTPUT-').Update(text)
        #Une fenêtre pop-up vous informera de la fin
        sg.Popup('A completé')

window.close()

En ce qui concerne l'interface graphique, il y a d'autres choses auxquelles j'ai beaucoup fait référence, donc je les posterai.

Notes d'apprentissage pour le séminaire K-TechLabo → Le texte PDF est très simple à comprendre.

■ Code source (complété)

import os
import sys
from PIL import Image

import PySimpleGUI as sg
import pyocr
import pyocr.builders


def scan_file_to_str(file_path, langage):
   """read_file_to_str

Générer une chaîne à partir d'un fichier image

        Args:
            file_path(str):Chemin du fichier à lire
            langage(str): 'jpn'Ou'eng'

        Returns:
Lire la chaîne de caractères
   """
   tools = pyocr.get_available_tools()
   if len(tools) == 0:
      print("No OCR tool found")
      sys.exit(1)

   tool = tools[0]

   text = tool.image_to_string(
      Image.open(file_path),
      lang=langage,
      builder=pyocr.builders.TextBuilder(tesseract_layout=6)
   )
   return text


#Définir le thème
sg.theme('Light Grey1')

layout = [
   #La première ligne
   [sg.Text('Fichier à lire(Plusieurs sélections possibles)', font=('IPA gothique', 16))],
   #2e ligne
   [sg.InputText(font=('IPA gothique', 14), size=(70, 10),), sg.FilesBrowse('Sélectionnez les fichiers', key='-FILES-'),],
   #3e ligne
   [sg.Text('Langue à lire', font=('IPA gothique', 16)), 
   sg.Radio('Japonais', 1, key='-jpn-', font=('IPA gothique', 10)),
   sg.Radio('Anglais', 1, key='-eng-', font=('IPA gothique', 10))],
   #4ème ligne
   [sg.Button('Lire l'exécution'),],
   #5ème ligne
   [sg.MLine(font=('IPA gothique', 14), size=(100,30), key='-OUTPUT-'),]
]

#Obtenir la fenêtre
window = sg.Window('OCR facile', layout)

files = []

a = 0

while True:
   event, values = window.read()
   if event == None:
      break

   if event == 'Lire l'exécution':
      files.extend(values['-FILES-'].split(';'))
      language = 'jpn' if values['-jpn-'] else 'eng'
      text = ''
      for i in range(len(files)):
         if not i == 0:
            text += '================================================================================================\n'
         text += scan_file_to_str(files[i], language)
         if language == 'jpn':
            text = text.replace(' ', '')
         text += '\n\n'
      window.FindElement('-OUTPUT-').Update(text)
      sg.Popup('A completé')

window.close()
スクリーンショット 2020-05-06 22.45.44.png

Laisse-moi lire deux images

[Anglais 1er (tiré du Bâtiment de la Maison Blanche)] スクリーンショット 2020-05-06 22.47.50.png

[2e anglais] スクリーンショット 2020-05-06 22.48.00.png

【résultat】 スクリーンショット 2020-05-06 22.59.50.png

Je pense que l'anglais est rapide à lire et assez précis.

[Japonais (d'Aozora Bunko)]

スクリーンショット 2020-05-06 22.56.34.png

【résultat】 スクリーンショット 2020-05-06 22.58.45.png

Le japonais prend du temps. Pourtant, la précision est à un niveau qui semble utilisable.

■ Enfin

En fait, je voulais faire de cette application un fichier exécutable qui fonctionne sur le bureau de Mac ou Windows, mais ni pyinstaller ni py2app ne fonctionnaient bien, j'ai donc décidé d'écrire un article dans cet état. Si je peux le faire à l'avenir, je le mettrai à jour.

Aussi, si vous avez des suggestions, des opinions ou des suggestions telles que "N'est-ce pas différent ici?" Ou "Il existe un tel moyen ici", n'hésitez pas à écrire dans la section des commentaires.

Recommended Posts

J'ai essayé de créer une application OCR avec PySimpleGUI
J'ai essayé de créer une application de notification de publication à 2 canaux avec Python
J'ai essayé de créer une application todo en utilisant une bouteille avec python
J'ai essayé de créer une fonction de similitude d'image avec Python + OpenCV
J'ai essayé de détecter un objet avec M2Det!
J'ai créé un capteur d'ouverture / fermeture (lien Twitter) avec TWE-Lite-2525A
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé de trouver la classe alternative avec tensorflow
J'ai fait une application d'envoi de courrier simple avec tkinter de Python
J'ai essayé de créer diverses "données factices" avec Python faker
J'ai essayé de créer une interface graphique à trois yeux côte à côte avec Python et Tkinter
J'ai essayé de créer un article dans Wiki.js avec SQL Alchemy
[5e] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une activité qui définit collectivement les informations de position
J'ai essayé d'envoyer un SMS avec Twilio
J'ai essayé d'implémenter Autoencoder avec TensorFlow
[2nd] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de visualiser AutoEncoder avec TensorFlow
J'ai essayé de rendre le deep learning évolutif avec Spark × Keras × Docker
J'ai essayé de commencer avec Hy
[3ème] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire un processus d'exécution périodique avec Selenium et Python
J'ai essayé de faire 5 modèles de base d'analyse en 3 ans
Je veux faire un programme d'automatisation!
[4th] J'ai essayé de créer un certain outil de type Authenticator avec python
[1er] J'ai essayé de créer un certain outil de type Authenticator avec python
J'ai essayé de faire une étrange citation pour Jojo avec LSTM
J'ai essayé de créer un mécanisme de contrôle exclusif avec Go
J'ai essayé de créer un langage original "PPAP Script" qui imagé PPAP (Pen Pineapple Appo Pen) avec Python
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
[AWS] [GCP] J'ai essayé de rendre les services cloud faciles à utiliser avec Python
[Zaif] J'ai essayé de faciliter le commerce de devises virtuelles avec Python
J'ai essayé de créer un service de raccourcissement d'url sans serveur avec AWS CDK
J'ai essayé de prédire l'année prochaine avec l'IA
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai essayé d'utiliser lightGBM, xg boost avec Boruta
J'ai essayé d'apprendre le fonctionnement logique avec TF Learn
J'ai essayé de déplacer GAN (mnist) avec keras
J'ai essayé "License OCR" avec l'API Google Vision
J'ai essayé d'obtenir une image en grattant
J'ai essayé de sauvegarder les données avec discorde
J'ai essayé de détecter rapidement un mouvement avec OpenCV
J'ai essayé d'intégrer Keras dans TFv1.1
Je veux faire un jeu avec Python
Je veux être OREMO avec setParam!
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé de faire de l'IA pour Smash Bra
J'ai essayé d'automatiser la fabrication des sushis avec python
J'ai essayé "Receipt OCR" avec l'API Google Vision
J'ai essayé d'utiliser Linux avec Discord Bot
J'ai essayé d'envoyer un email avec SendGrid + Python
J'ai essayé d'étudier DP avec séquence de Fibonacci
J'ai essayé de démarrer Jupyter avec toutes les lumières d'Amazon
J'ai essayé de juger Tundele avec Naive Bays
J'ai créé un jeu ○ ✕ avec TensorFlow
J'ai essayé de déboguer.