Raspberry PiでOCRを使うでRaspberry PiにTesseract-OCRをインストールしてOCRできるようにしたが、これとTwitterを利用して、Python3でOCRボットを作る。
OSはRaspbian Jessie。
以下の事項を済ませておく。
PythonでTesseract-OCRを使うためにPythonラッパーのPython-tesseractをインストールする。ただその前に、libjpeg8-devと画像処理ライブラリのPillowをインストールしておく。libjpeg8-devはjpg画像を扱うのに必要。
続いてPython-tesseractのインストール。
Pillowとpytesseractのバージョンは以下の通り。
はじめにTesseract-OCRのパスを確認しておく。
使い方は簡単。tesseractのパスを設定して、OCRする画像を読み込むだけ。日本語OCRの精度に不安はあるが(Raspberry PiでOCRを使う)、とりあえずこれで進める。
PythonでOCRできるようになったので、次はTwitter APIを利用できるようにする。Python3でTwitterのデータを取得するではTweepyというTwitter APIのPythonラッパーを使ったが、ここではRequests-OAuthlibというHTTPライブラリのRequestsをサポートするOAuth認証ライブラリを使用する。Requests-OAuthlibはpipでインストール。
以下のバージョンがインストールされた。
Twitterが提供するAPIには、過去データを取得できるTwitter APIだけでなく、リアルタイムにデータ取得できるStreaming APIもある。Streaming APIを使ってリアルタイムに特定キーワードを含むツイートを検索してみる。Streaming APIを利用するサンプルはRequestsのページにあるので、これを参考に以下のようなサンプルコードを作成。
上記コードをPython3で実行すると、以下のように「ラーメン」を含むツイートが表示される。
要領としては、TwitterとPythonでRaspberry Piを再起動するでやったように、Twitterのダイレクトメッセージを使う。スマホから自分宛にダイレクトメッセージで画像を送信し、Raspberry Piで画像のURLを含むダイレクトメッセージを受信する。画像をダウンロードしてからOCRして、結果を自分宛に返信すると、スマホでOCRの結果を受け取れる。以下のコードを作成。
上記コードをPython3で実行し、スマホで撮った画像をTwitterのダイレクトメッセージで自分宛に送る。送ったのは以下2つの画像。解像度はそれぞれ4050 X 719と3898 X 850。
Twitterの遅延なのか数分遅れることがあるものの、ちゃんと動いている。ただ、OCRの精度はイマイチ。実用は難しいか・・・
環境
OSはRaspbian Jessie。
事前準備
以下の事項を済ませておく。
- Tesseract-OCRのインストール(Raspberry PiでOCRを使う)
- Twitter APIの利用に必要なAPIキーとトークンの取得(Twitterの開発者向けのページで申請する)
PythonラッパーPython-tesseractのインストール
PythonでTesseract-OCRを使うためにPythonラッパーのPython-tesseractをインストールする。ただその前に、libjpeg8-devと画像処理ライブラリのPillowをインストールしておく。libjpeg8-devはjpg画像を扱うのに必要。
続いてPython-tesseractのインストール。
Pillowとpytesseractのバージョンは以下の通り。
Python-tesseractを使ってみる
はじめにTesseract-OCRのパスを確認しておく。
使い方は簡単。tesseractのパスを設定して、OCRする画像を読み込むだけ。日本語OCRの精度に不安はあるが(Raspberry PiでOCRを使う)、とりあえずこれで進める。
1 2 3 4 5 6 7 8 | from PIL import Image import pytesseract # tesseractのパスを設定 pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' # text.pngという画像を日本語OCRして結果を出力 print (pytesseract.image_to_string(Image. open ( 'test.png' ), lang = 'jpn' )) |
Requests-OAuthlibによるStreaming APIの利用
PythonでOCRできるようになったので、次はTwitter APIを利用できるようにする。Python3でTwitterのデータを取得するではTweepyというTwitter APIのPythonラッパーを使ったが、ここではRequests-OAuthlibというHTTPライブラリのRequestsをサポートするOAuth認証ライブラリを使用する。Requests-OAuthlibはpipでインストール。
以下のバージョンがインストールされた。
Twitterが提供するAPIには、過去データを取得できるTwitter APIだけでなく、リアルタイムにデータ取得できるStreaming APIもある。Streaming APIを使ってリアルタイムに特定キーワードを含むツイートを検索してみる。Streaming APIを利用するサンプルはRequestsのページにあるので、これを参考に以下のようなサンプルコードを作成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import json from requests_oauthlib import OAuth1Session, OAuth1 # Twitter APIの認証情報 # Twitterの開発者向けのページで取得したキーとトークンを使う CONSUMER_KEY = 'Consumer Key' CONSUMER_SECRET = 'Consumer Secret' ACCESS_TOKEN = 'Access Token' ACCESS_TOKEN_SECRET = 'Access Token Secret' # 認証情報の設定 tw = OAuth1Session(CONSUMER_KEY, client_secret = CONSUMER_SECRET, resource_owner_key = ACCESS_TOKEN, resource_owner_secret = ACCESS_TOKEN_SECRET) # Twitterデータのリアルタイム検索 # https://developer.twitter.com/en/docs/tweets/filter-realtime/api-reference/post-statuses-filter.html # 検索キーワードの指定 data = { 'track' : 'ラーメン' } # Streaming APIを使うときはオプションstream=Trueを指定 r = tw.post(url, data = data, stream = True ) for line in r.iter_lines(): if line: status = json.loads(line.decode( 'utf-8' )) # ツイートを表示 print (status[ 'text' ] + '\n' ) |
上記コードをPython3で実行すると、以下のように「ラーメン」を含むツイートが表示される。
OCRボットの作成
要領としては、TwitterとPythonでRaspberry Piを再起動するでやったように、Twitterのダイレクトメッセージを使う。スマホから自分宛にダイレクトメッセージで画像を送信し、Raspberry Piで画像のURLを含むダイレクトメッセージを受信する。画像をダウンロードしてからOCRして、結果を自分宛に返信すると、スマホでOCRの結果を受け取れる。以下のコードを作成。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | """ Twitterのダイレクトメッセージで送信した画像をOCRして返信する """ import os import json import uuid from io import BytesIO from requests_oauthlib import OAuth1Session, OAuth1 from PIL import Image import pytesseract # Twitter APIの認証情報 # Twitterの開発者向けのページで取得したキーとトークンを使う CONSUMER_KEY = 'Consumer Key' CONSUMER_SECRET = 'Consumer Secret' ACCESS_TOKEN = 'Access Token' ACCESS_TOKEN_SECRET = 'Access Token Secret' # Twitterの認証情報でOAuth1Sessionオブジェクト作成 tw = OAuth1Session(CONSUMER_KEY, client_secret = CONSUMER_SECRET, resource_owner_key = ACCESS_TOKEN, resource_owner_secret = ACCESS_TOKEN_SECRET) # pytesseractのパスを設定 pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract' def send_dm(sn, text): """ ダイレクトメッセージの送信 """ data = { 'screen_name' :sn, 'text' :text} def dl(url): """ ダイレクトメッセージに添付された画像ファイルのダウンロード """ # ダイレクトメッセージに添付された画像のURLにHTTPリクエスト r = tw.get(url) # HTTPリクエストのレスポンスから画像データ作成 img = Image. open (BytesIO(r.content)) # 画像ファイルの拡張子を取得 root, ext = os.path.splitext(url) # UUIDでユニークなファイル名を作成して画像を保存 uname = str (uuid.uuid4()) img.save(uname + ext) return uname + ext def get_text(img_path): """ pytesseractを使ってOCRした結果を返す """ return pytesseract.image_to_string(Image. open (img_path), lang = 'jpn+eng' ) def streaming(): """ Streaming APIでダイレクトメッセージを受信して、画像があればOCRして 結果をダイレクトメッセージで送信する """ # Stream APIを使うときはオプションstream=Trueを指定 print ( 'Ready to OCR' ) for line in r.iter_lines(): if line: line = line.decode( 'utf-8' ) else : continue if 'direct_message' in line: # JSONから辞書型に変換 dm = json.loads(line)[ 'direct_message' ] # 送信者と受信者の一致をチェック # 他人からのDirect Messageに反応しないようにするため if dm[ 'sender_screen_name' ] = = dm[ 'recipient_screen_name' ]: if 'entities' in dm: if 'media' in dm[ 'entities' ]: print ( 'DM: {} from @{}' . format (dm[ 'text' ], dm[ 'sender_screen_name' ])) for media in dm[ 'entities' ][ 'media' ]: # 画像ファイルのURL img_url = media[ 'media_url' ] # 画像をダウンロード fname = dl(img_url) # ダウンロードした画像をOCR ocr_text = get_text(fname) print (ocr_text) # ダイレクトメッセージでOCRの結果を送信 send_dm(dm[ 'sender_screen_name' ], ocr_text) # 画像ファイルの削除 os.remove(fname) if __name__ = = '__main__' : streaming() |
上記コードをPython3で実行し、スマホで撮った画像をTwitterのダイレクトメッセージで自分宛に送る。送ったのは以下2つの画像。解像度はそれぞれ4050 X 719と3898 X 850。


Twitterの遅延なのか数分遅れることがあるものの、ちゃんと動いている。ただ、OCRの精度はイマイチ。実用は難しいか・・・

0 件のコメント:
コメントを投稿