[業務改善]ChatGPTに、表データが記載された紙を読み込み、表を再現する機能をつくってもらった!(pytesseract, OCR)
以前ChatGPTに作ってもらった「文字画像を抽出する機能」が使えそうなので、もうちょっとカスタマイズしてみることにしました。
今回もChatGPTを使用して、表データが記載された画像ファイルを読み込み、表形式で画面表示するような機能を作成していこうと思います。
以前ChatGPTに作ってもらった「文字画像を抽出する機能」
目的
手作業をなくし、すべての工程を自動化することを目標として、検討を進めて参ります。
紙データを手書きで転記する必要がなくなり、さらにデジタルデータを整形することができる
「文字画像を抽出する機能」を使用すれば、紙からデジタルに移行する際に、手で書き写す必要がなくなりますし、独自のフォーマットに応じて、デジタルデータ化する際にプログラミングすることでカスタマイズできますので、そのあたりは作るメリットがあるのかなと。
デジタル化したあとに、そのデジタルデータを整形し直す工程を極力少なくすることを目標に作っていこうと思います!
表が記載された画像データをどのように取り込むかを検討する
表が記載された画像データを表形式として取り込む方法を考えていきます!
まずはChatGPTに聞いてみようと思います。
プロンプト
画像ファイルから表形式のデータを抽出したいです
ChatGPTの回答(コード箇所は割愛)
表を再現するには、テキストを解析し、改行やスペースなどを頼りに表を作る
表を再現するには、テキストを解析し、改行やスペースなどを頼りに表となるように組み立てていくみたいですので、専用の加工処理が必要になってきそうです。
一撃では、いい感じの表形式にならなそうですね、、
イメージ的には、画像ファイルから以下のように文字を抽出し、このデータの内容で表形式を作れば、表が再現できるようなイメージです。
ああ[スペース]いい[スペース]うう[スペース]ええ[改行]
かか[スペース]きき[スペース]くく[スペース]けけ[改行]
設計イメージを作る
次に設計イメージを作っていきます。
設計イメージを作ると、作成する機能を整理できる
設計イメージを作ることで、これから作成する機能を整理できるのと、中断した際に作成内容を思い出すのに楽ですし。
作成する機能は、「画像ファイルを読み込み、表形式で画面表示する」
赤枠が今回の作成する箇所です。
表データが記載された画像ファイルを読み込み、最終的に表形式で画面表示するような機能を作成していこうと思います。
後日、表データをPDF化やエクセル化していくなど、さらに機能追加をしていこうかと思います。ベースの機能があると色々な機能に応用しやすいですね。
設計イメージもChatGPTと一緒に作る
上記設計イメージを作る際にも、ChatGPTに「画像ファイルを読み込み、表形式で画面表示する」コードを教えてもらい、そのコードの内容を参考に、どのようなコードを作っていくかをフローとして簡単にまとめていきます。
ChatGPTへの指示出しは、少ないコード量でまとまるような指示の方が、微調整しやすい
ChatGPTにコーディング依頼をする際には、長文の指示でコード量が多いコーディングより、少ないコード量でまとまるような指示の方が、微調整しやすいのと、今後の改修もしやすいので、ファンクション単位での指示を出すのが良いかと思います。どのあたりをファンクションとして切り出すのを検討するのに設計メモは参考になります。
動作確認その1
ChatGPTに作ってもらったコーディングについては、以前に作成したもの(上記リンク)と、そこまで大幅に変わらないので割愛します。
読み取り対象の画像ファイル
ちょうど表形式の画像ファイルがあったので、このスクショ画像を使っていきます。(以前ChatGPTで作ったもの)
結果
おっと・・!
全然表になりませんね、、
読み取り対象の画像ファイルと比較すると、左上から右側に読み込まれておりませんね、、
左上から右側に読み込まれる方法についてChatGPTに聞く
プロンプト
pytesseract.image_to_string
上記、表形式のデータを読み込みたいのですが、 左から右に読み込まれず、左から下に読み込んでしまいます
プロンプト
上記2について、具体的なやり方を教えてください
import pytesseract
from PIL import Image
# 画像からテキストをOCR処理して抽出する関数
def extract_text_from_image(image_path):
try:
# 画像を開く
image = Image.open(image_path)
# 画像からテキストを抽出
text = pytesseract.image_to_string(image, lang='jpn', psm=6, oem=3) # 日本語の場合の設定例
return text
except Exception as e:
print("テキストの抽出中にエラーが発生しました:", e)
return None
# 使用例
image_path = 'path/to/your/image.jpg'
text = extract_text_from_image(image_path)
print(text)
pytesseract.image_to_stringの設定値で微調整ができる
pytesseract.image_to_stringの引数の設定(テキストの方向の設定: psm、ページのセグメンテーション: oem)により、微調整できるとのことです。
psmとoemのそれぞれのモードをChatGPTに聞いたところ、ネットで調べた内容と色々と異なっていたので、モードの記載は割愛します。
また、上記でChatGPTに教えてもらったコードではエラーとなり、エラーメッセージを伝えたところエラーとならないロジックを提示してくれました、、
修正前
text = pytesseract.image_to_string(image, lang='jpn', psm=6, oem=3)
修正後
# psmとoemのパラメータが未指定の場合は、デフォルト値を設定する
config = f'--psm {psm}' if psm is not None else ''
config += f' --oem {oem}' if oem is not None else ''
# 画像からテキストを抽出して返す
text = pytesseract.image_to_string(image, lang='jpn', config=config)
動作確認その2
pytesseract.image_to_stringの設定値が、psm=6, oem=3となるように設定し、動作確認!
読み取り結果
今度は左上から右側へ読みこんでくれました!
ただ表としてはかなり崩れてしまってますね、、
pytesseract.image_to_stringの抽出内容として、何の空白文字や制御文字が返却されるか精査する
ChatGPTに、「pytesseract.image_to_stringの抽出内容として、何の空白文字や制御文字が返却されるか」を聞いたところ、思った通りの回答とならなかったので、1文字ずつ文字コードをデバックするコードをChatGPTに作ってもらいました。
返却された制御文字は、改行コードと半角スペースのみ
上記ChatGPTに作ってもらったコードを実行したところ、返却された制御文字は、改行コードと半角スペースのみで、タブ文字はありませんでした。
Character Code: 10 改行コード
Character Code: 32 半角スペース
Character: 変, Character Code: 22793
Character: 更, Character Code: 26356
Character:
, Character Code: 10
Character: 1, Character Code: 49
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: , Character Code: 32
Character: 山, Character Code: 23665
Character: 田, Character Code: 30000
Character: , Character Code: 32
Character: 太, Character Code: 22826
Character: 郎, Character Code: 37070
Character: , Character Code: 32
半角スペースが複数続いた場合は、半角スペース1つに置換する
一旦、半角スペースが複数続いた場合は、半角スペース1つに置換することにしました。
表形式のデータとしては、未入力のカラムも存在するので、この対応では元データの内容によってはずれてしまうので、よろしくないのですが一旦このロジックで実施し、未入力パターンについてはその後検討しようと思います、、
動作確認その3
上記修正後に動作確認をしたところ、ようやく表が再現することができました!
あとは本来、表でないところは、表形式としないようなロジックとすれば大体のまとまってきそうです!
おわりに
最後まで読んで頂き、ありがとうございます!
まだ完成はしていませんが、記事が長くなってきたので、このあたりで終わりにしようと思います、、
取り込む表データのバリエーションはまだ少なく、課題がまだ残っている状況ですが、機能のベースができ、方向性も固まってきたので、今後もChatGPTと共にこのシステムを拡張していきたいと思います!
おまけ
最近クイズサイトを作りました!
1問でも実施していただけると嬉しいです!!!
それと、ChatGPTを使用し、色々なことを模索しています。
もしよければ、以下の記事も見て頂けると嬉しいです!