DjangoでOCRアプリを作成してみます。
画像から文字を読み取るのにAzureのCognitive Servicesを使用します。
環境
- Windows10
- Python 3.8.3
- Azure Cognitive Services Computer Vision API
事前準備
pipenvを利用して開発を行うため、pipenvを導入しておきます。
1 |
pip install pipenv |
django_ocrフォルダを作成し、カレントフォルダをdjango_ocrに変更します。
1 2 |
mkdir django_ocr cd django_ocr |
pipenvを利用してDjangoの2.2の最新バージョン、requests、pillowをインストールします。
1 |
pipenv install django==2.2.14 requests pillow |
pipenvの仮想環境を有効化します。
1 |
pipenv shell |
DjangoでOCRアプリケーションの作成
プロジェクトを作成します。django_ocr_projectのあとに半角スペースで間隔を開けて
.(ドット)を入力します。
1 |
django-admin startproject django_ocr_project . |
django_ocr_projectフォルダが作成されるのでsettings.py内の
LANGUAGE_CODEとTIME_ZONEを変更します。
1 2 |
LANGUAGE_CODE = 'ja' TIME_ZONE = 'Asia/Tokyo' |
ocrアプリケーションを追加します。
1 |
python manage.py startapp ocr |
settings.pyのINSTALLED_APPSにocrのアプリケーションを追加します。
1 2 3 4 5 6 7 8 9 |
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'ocr.apps.OcrConfig', #追加 ] |
django_ocr_projectフォルダ内のurls.pyを変更します。
1 2 3 4 5 6 7 |
from django.contrib import admin from django.urls import path, include # 追加 urlpatterns = [ path('admin/', admin.site.urls), path('', include('ocr.urls')), # 追加 ] |
ocrフォルダ内にurls.pyを追加して、内容を以下のようにします。
1 2 3 4 5 6 7 8 |
from django.urls import path from . import views app_name = 'ocr' urlpatterns = [ path('', views.OCR.as_view(), name='ocrform'), ] |
ocrフォルダ内のviews.pyを変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
from django.views import generic from .forms import OCRForm class OCR(generic.FormView): form_class = OCRForm template_name = 'ocr/ocr.html' def form_valid(self, form): response_str = form.read_str() context = { 'response_str': response_str, 'form': form, } return self.render_to_response(context) |
ocrフォルダ内にtemplatesフォルダを作成し、さらにtemplatesフォルダ内にocrフォルダを作成します。
ocr/templates/ocrフォルダ内にocr.htmlを作成し、画像アップロード用のテンプレートファイルを作成します。
1 2 3 4 5 6 7 |
django_ocr |-django_ocr_project |-ocr | |-templates | |-ocr | |-ocr.html |-manage.py |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>OCR</title> </head> <body> <form action="" method="POST" enctype="multipart/form-data"> {{ form.as_p }} {% csrf_token %} <button type="submit">送信</button> </form> {% if response_str %} <p>{{ response_str | linebreaks }}</p> {% endif %} </body> </html> |
ocrフォルダ内にforms.pyを追加し,画像アップロード用のクラスを作成します。
subscription_keyにはAzureのComputer Visionでリソース作成後に発行されるAPIキーを入力してください。
ocr_urlにはComputer Visionでリソース作成後に発行されるエンドポイントURLとvision/v3.0/ocrを組み合わせたURLを設定します
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
from django import forms import requests from .parsejson import parse_json_response class OCRForm(forms.Form): file = forms.ImageField(label='画像ファイル') def read_str(self): upload_file = self.cleaned_data['file'] read_file = upload_file.read() subscription_key = 'Computer Vision APIから発行されたキーを入力' ocr_url = 'Computer Vision APIのエンドポイントURL' + 'vision/v3.0/ocr' headers = {'Ocp-Apim-Subscription-Key': subscription_key, 'Content-Type': 'application/octet-stream'} params = {'language': 'unk', 'detectOrientation': 'true'} response = requests.post(ocr_url, headers=headers, params=params, data=read_file) response_str = parse_json_response(response.json()) return response_str |
ocrフォルダ内にparsejson.pyを追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
def parse_json_response(json_dic): language = json_dic['language'] word_space = '' if language == 'zh-Hans' or language == 'zh-Hant' or language == 'ja' or language == 'ko': pass else: word_space = ' ' lines = json_dic['regions'][0]['lines'] result = '' for line in lines: for word in line['words']: result += word['text'] + word_space result = result.rstrip() result += '\n' if result == '': result = '画像から文字を読み込めませんでした' return result |
動作確認
runserverコマンドで動作を確認してみます
1 |
python manage.py runserver |
ブラウザで http://127.0.0.1:8000 にアクセスすると画像アップロード用のページが表示されます。
「ファイルを選択ボタン」を押して文字を読み取りたい画像を選択します。
別記事の文章を画像化したものをテストで取り込んでみます。
画像を選択した状態で「送信」ボタンを押すと処理を開始します。
画像から文字を読み取った結果を送信ボタンの下に表示します。
今回テストで使用した画像の文字を、ほぼ正確に読み取れています。
コメント