5

画像の数式をlatexに変換する

1976
0
$$$$

こんにちは、受験勉強から逃げてきたitouです。

今回はpythonでlatexのOCRをやってみたよ、という話です。

mathlogを見ていると、「この人の記事面白い!自分も記事書こ~、でもこんな式latexに打つのがめんどくさい……」ということありますよね。そんな時、役に立つのがOCRです。自動で数式をlatexにしてくれます!

OCRとは?

Optical character recognition(光学文字認識)のことで、画像をテキストに変換するプログラムのこと。

LATEXに変換してくれるソフトとしては mathpix が提供するサービスの mathpixsnip がおすすめです。ただしfree版では月10回までしか使えません。(educational版は月20回、Pro版は月5ドルで5000回) 参考

お金をかけたくない。しかし月10回は少ない。そこでpythonを使いましょう。

必要なもの

pythonの開発環境だけです。

やり方

githubの このページ にあるように、LatexOCRモジュールを無料でインストールできます。で、次のコードをコピペしてください。

      
# -*- coding: utf-8 -*-

from PIL import Image
import PySimpleGUI as sg
from PIL import Image
from pix2tex.cli import LatexOCR
import sys
import os
from PIL import Image

from PyQt6.QtWidgets import QApplication, QMainWindow, QLabel, QPushButton, QTextEdit, QFileDialog, QRadioButton, QVBoxLayout, QWidget, QMessageBox
import threading
import pyocr
import pyocr.builders

class OCRApp(QMainWindow):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        self.setWindowTitle('簡単OCR')
        self.setGeometry(100, 100, 800, 600)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        self.layout = QVBoxLayout()

        self.file_label = QLabel('読み取るファイル(複数選択可)')
        self.layout.addWidget(self.file_label)

        self.file_text_edit = QTextEdit()
        self.layout.addWidget(self.file_text_edit)

        self.browse_button = QPushButton('ファイルを選択', self)
        self.browse_button.clicked.connect(self.browse_files)
        self.layout.addWidget(self.browse_button)

       

        self.execute_button = QPushButton('読み取り実行', self)
        self.execute_button.clicked.connect(self.execute_ocr)
        self.layout.addWidget(self.execute_button)

        self.output_text_edit = QTextEdit()
        self.layout.addWidget(self.output_text_edit)

        self.central_widget.setLayout(self.layout)

        self.files = []

    def browse_files(self):
        file_dialog = QFileDialog()
        files, _ = file_dialog.getOpenFileNames(self, 'ファイルを選択', '', 'Image Files (*.png *.jpg *.jpeg *.bmp);;All Files (*)')

        if files:
            self.files.extend(files)
            self.file_text_edit.setPlainText('\n'.join(self.files))

    def execute_ocr(self):
        if not self.files:
            return

  

        text = ''
        for i, file_path in enumerate(self.files):
            if i != 0:
                text += '================================================================================================\n'
            text += self.scan_file_to_str(file_path)
       
            text += '\n\n'

        self.output_text_edit.setPlainText(text)

    

    def scan_file_to_str(self,file_path):
        img = Image.open(file_path)
        model = LatexOCR()
        text = model(img)
        return text


    

実行すると数秒後次のウィンドウがでてきます。

ウィンドウ ウィンドウ

ここで「ファイルを選択」をクリックし、変換したい画像ファイルを選択します。そして「読み取り実行」を押すだけです。そこそこ時間がかかります。

例 
私の記事の画像 私の記事の画像

を変換すると

$\begin{array}{r l}{(n+1)^{2}u_{n+1}(x_{0},x_{1},x_{2})|a,b\rangle=(x_{0}n^{2}+x_{0}n+x_{1})u_{n}(x_{0},x_{1},x_{2})t_{a_{1}})}\\ {=(x_{0}n^{2}+x_{0}n_{1})u_{n}(x_{0}^{2},x_{1},{\frac{x_{2}}{m^{2}}})(a,{\frac{b}{m}})\times m^{n+1}}\\ {=(n+1)^{2}u_{n+1}({\frac{x_{0}}{m}},{\frac{x_{1}}{m^{2}}})(x,{\frac{b}{m}})\times m^{n+1}}\end{array} $
ちょっと数式が変わってますが、誤差の範囲です。

所感

便利ですね!モジュールの作者の@lukas-blecher
lukas-blecher zsh #301さんに感謝します。手書きの文字とかはうまくいかないこともあります。大学生や研究者はみんなmathpixsnipを使っているのでしょうか?mathlogには中高生も多いので、需要はあるかな?

投稿日:2023918
OptHub AI Competition

この記事を高評価した人

高評価したユーザはいません

この記事に送られたバッジ

バッジはありません。

投稿者

itou
itou
139
11802
数学勉強中. https://twitter.com/G7UOMb0Zd8V7LdP

コメント

他の人のコメント

コメントはありません。
読み込み中...
読み込み中