1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PaddleOCR+Ktor+Next.jsで文字認識Webアプリ

Last updated at Posted at 2024-11-01

はじめに

概要

本記事では、OCRを実施する簡単なWebアプリケーションを紹介します。
コードは全てGithubにアップしております。

OCRとは

OCRとは「Optical Character Recognition」の略で、光学式文字認識を指します。
今回のデモアプリでは、Clientのブラウザからサーバに画像ファイルをアップロードする事で、画像内から文字列を読み取ります。

PaddleOCRとは

80言語以上をサポートしているPythonの軽量OSSライブラリです。
トレーニング済みのモデルが公開されてるため、すぐにOCRを試すことができます。

本編

アーキテクチャ

フロントからバックエンドに画像を投げ、バックエンドで非同期にOCRを実行します。実行ステータスはバックエンドのPostgreSQLで管理し、フロントはポーリングで実行完了を待ちます。

フロントエンド
 Next.js + React

バックエンド
 KtorのWebアプリ + PythonのOCRロジック実行環境

環境

OSは一応Windowsですが、Linuxでも動作すると思います。
主なフレームワーク/ライブラリのみ記載します。

フロントエンド

  • Next.js / React: 14.2.15
  • typescript: 5
  • tailwind css: 3.4.14

バックエンド

  • ktor: 2.3.12
  • exposed: 0.53.0
  • postgres: 14.6
    (下記よりpython環境)
  • python: 3.9.6 
  • PaddleOCR: 2.7.0.3
  • paddlepaddle: 2.5.2
  • loguru: 0.7.2

ソースコード

GithubのRepositoryを参照ください。
OCRロジックは、バックエンドのリソースに含まれるocr_demo.pyに実装してます。このファイル単体でもOCRを試せます。
フロントエンド
バックエンド

OCRロジック

ocr_demo.py (一部抜粋)
def run_ocr(img_path):
    # 画像パスからnumpy配列へ
    img = Image.open(img_path).convert('L')
    np_img = np.asarray(img)
    
    paddleOCR = PaddleOCR(
        use_gpu=False, # GPUは使用しない
        lang = "en", # 今回は英語の学習モデル
        det_limit_side_len=img.size[1], # 画像の圧縮防止
        max_text_length = 20, # 検知する文字列長
        show_log=False
        )
        
    result = paddleOCR.ocr(img=np.asarray(np_img), det=True, rec=True, cls=False)
    if not result or result[0] is None:
        logger.debug(f'not detected.')
        return
    
    # 検知文字列を画像に入力
    output_img = cv2.cvtColor(np_img.copy(), cv2.COLOR_BGR2RGB)
    for detection in result[0]:
        top_left = tuple([int(i) for i in detection[0][0]])
        bottom_right = tuple([int(i) for i in detection[0][2]])
        bottom_left = tuple([int(i) for i in detection[0][3]])
        found_text = detection[1][0]
        
        output_img = cv2.rectangle(output_img, top_left, bottom_right, (0, 255, 0), 1)
        output_img = cv2.putText(output_img, found_text, top_left, cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 1, cv2.LINE_AA)

    # 結果画像保存
    output_img = cv2.cvtColor(output_img, cv2.COLOR_RGB2BGR)
    cv2.imwrite(img_path, output_img)

Demo

OcrDemo.gif

躓いた点

PaddleOCRの実行環境構築に苦戦しました。
python・paddleocr・paddlepaddleのバージョンで、互換性の無い組合わせがあります。
本家のGithubに従っても良いのですが、私は下記の組合せで動作確認してます。

※python 3.9.6
python -m pip install paddleocr==2.7.0.3
python -m pip install paddlepaddle==2.5.2 -i https://mirror.baidu.com/pypi/simple

蛇足

今回の仕様/コードでは、フロント・バックを分けてNext.jsを用いる意味が全くないのですが・・・
この構成をサッと試せる環境を作っておきたかったです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?