質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Google Cloud Platform

Google Cloud Platformは、Google社がクラウド上で提供しているサービス郡の総称です。エンドユーザー向けサービスと同様のインフラストラクチャーで運営されており、Webサイト開発から複雑なアプリ開発まで対応可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1410閲覧

Google Cloud Vision の OCR で、認識されている文章は正しいが、文字を分割している矩形の位置がズレてしまう。

namagon

総合スコア5

Google Cloud Platform

Google Cloud Platformは、Google社がクラウド上で提供しているサービス郡の総称です。エンドユーザー向けサービスと同様のインフラストラクチャーで運営されており、Webサイト開発から複雑なアプリ開発まで対応可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/09/19 11:13

編集2018/09/19 12:36

発生している問題・エラーメッセージ

Google Cloud Vision (以下GCV) の DOCUMENT_TEXT_DETECTION を利用しています。
OCR にて文字列は正しく検知されているにもかかわらず、文字分割の認識領域がズレているように見られます。
単独文字の confidence も高いため、検知箇所を間違えているということも考えづらいです。
以下の仮説を検証中していますが、詰まってしまいました。

  • 私が書いた描画関数がポンコツ
  • GCV の character segmentation がポンコツ
  • GCV の 内部で画像に何かしらの補正をかけている。
  • その他

実現したいこと

Cloud Vision の 文字分割の結果を元に、画像中の文字から1文字ずつトリミングした画像郡を生成したいと思いっています。
そのためになぜ矩形の位置がズレているのか、補正する方法があるのかを知りたいです。
よろしくお願いします。

入力画像

入力画像

Cloud Vision API から帰ってきた Json ファイル

147475.json

文字分割の認識領域を描画した画像

文字分割の認識領域を描画した画像

描画関数

現在試しに書いているソースから描画に関するところだけ抜いてきたので
至らないところは目をつぶっていただけると助かります。

py

1import argparse 2import cv2 3import glob 4import json 5 6def get_coordinate_list(json_data): 7 json_list = json_data['responses'][0]['fullTextAnnotation']['pages'] 8 coordinate_list = [] 9 10 for pages in json_list: 11 for blocks in pages['blocks']: 12 for paragraphs in blocks['paragraphs']: 13 for words in paragraphs['words']: 14 for symbols in words['symbols']: 15 coordinate_list.append(symbols['boundingBox']) 16 17 return coordinate_list 18 19 20def read_image(img_file): 21 image_file = img_file 22 image = cv2.imread(str(image_file)) 23 cv2.destroyAllWindows() 24 return image 25 26 27def get_rectangle(img, lists, file_path): 28 for box in lists: 29 cv2.destroyAllWindows() 30 cv2.rectangle(img, (box['vertices'][0]['x'], box['vertices'][0]['y']), (box['vertices'][2]['x'], box['vertices'][2]['y']), (255, 255, 0), 4) 31 32 ext = ("_rectangle" + get_extension(file_path)) 33 cv2.imwrite(file_path + ext, img) 34 return file_path + ext 35 36 37if __name__ == '__main__': 38 parser = argparse.ArgumentParser() 39 parser.add_argument("--input", type=str) 40 args = parser.parse_args() 41 input_dir = args.input 42 43 # 描画対象のファイルを取得 44 file_list = list(glob.glob(input_dir + '/*.jpg') + glob.glob(input_dir + '/*.png')) 45 for file_path in file_list: 46 json_file = file_path + '.json' 47 f = open(json_file, 'r') 48 json_data = json.load(f) 49 rect_list = get_coordinate_list(json_data) 50 51 # 矩形を描画 52 img = read_image(file_path) 53 54 get_rectangle(img, rect_list, file_path) 55

補足情報

Python 3.6.5

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

確認しましたが、たしかに頂点情報をそのまま描画しても、ご指摘のようにズレますね。

python

1 2import json 3import math 4from pprint import pprint 5 6import matplotlib.patches as patches 7import matplotlib.pyplot as plt 8import numpy as np 9from PIL import Image 10 11# 画像 を読み込む。 12img_path = 'test.jpg' 13img = np.array(Image.open(img_path)) 14 15# json を読み込む。 16json_path = 'test.json' 17with open(json_path, encoding='utf-8') as f: 18 j = json.loads(f.read()) 19 20# json オブジェクトからデータ抽出 21######################################################### 22words = j['responses'][0]['fullTextAnnotation']\ 23 ['pages'][0]["blocks"][0]['paragraphs'][0]['words'] 24 25# symbol オブジェクトを解析する。 26def parse_symbol(symbol): 27 bbox = [] 28 for vertex in symbol['boundingBox']['vertices']: 29 bbox.append([vertex['x'], vertex['y']]) 30 31 return bbox, symbol['confidence'], symbol['text'] 32 33# json オブジェクトを解析する。 34bboxes = [] 35confs = [] 36words = [] 37 38pages = j['responses'][0]['fullTextAnnotation']['pages'] 39for page in pages: 40 for block in page['blocks']: 41 for paragraph in block['paragraphs']: 42 for word in paragraph['words']: 43 for symbol in word['symbols']: 44 bbox, conf, word = parse_symbol(symbol) 45 bboxes.append(bbox) 46 confs.append(conf) 47 words.append(word) 48 49# 可視化 50######################################################### 51 52# 画像表示用の Figure 53fig1, axes1 = plt.subplots(figsize=(6, 6)) 54axes1.imshow(img) 55 56# 文字表示用の Figure 57fig2 = plt.figure(figsize=(8, 18)) 58fig2.subplots_adjust(hspace=0.5) 59cols = 4 60rows = math.ceil(len(words) / cols) 61 62for i, (bbox, conf, word) in enumerate(zip(bboxes, confs, words)): 63 64 # 矩形を画像に描画する。 65 rect = patches.Polygon(bbox, color='g', fill=False) 66 axes1.add_patch(rect) 67 68 # 文字の部分を切り出して描画する。 69 axes2 = fig2.add_subplot(rows, cols, i + 1) 70 71 # 画像 72 tl, br = bbox[0], bbox[2] # 矩形の左上、右下の点 73 word_img = img[tl[1]:br[1], tl[0]:br[0], :] 74 axes2.imshow(word_img) 75 axes2.set_axis_off() 76 # タイトル 77 text = '{} {:.1%}'.format(word, conf) 78 axes2.set_title(text) 79 80plt.show()

イメージ説明

イメージ説明

原因の推測

座標値から観察できることは

  • 例えば「中」は矩形が文字と全く被っていないので、文字の切り出しが正確でないが、なんとか認識している線はありえない。
  • 全体に同じ量ずれているわけではない。
  • 画像に写る文字は正面から写っているとは限らない。その文字を長方形で表現するのは不可能 (文字が斜めに写っていたら、矩形は平行四辺形のような形になるはず)。だけど、結果として返ってくる4点の座標は長方形である。

ここから以下のことが推察されます。

  • 文字認識は「1文字単位の切り出し」→「文字の認識」の2段階で行われている。
  • 文字を切り出す前に、斜めから写っている画像をホモグラフィー変換等で正面から写る画像に補正している。
  • 矩形は補正後の画像の座標を返している。
  • 内部でどのような補正が行われているかわからないので、矩形から画像の文字の位置を復元するのは不可能。(例えば、ホモグラフィー変換の行列がわかれば、矩形の補正前の座標値は計算できる。)

同じ質問が Stack Overflow にもありましたが、解決はしていません。
答えが得られるかはわかりませんが、Google に問い合わせてみてはどうでしょうか?

投稿2018/09/20 03:40

tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

oikashinoa

2018/09/20 05:28

>文字を切り出す前に、斜めから写っている画像をホモグラフィー変換等で正面から写る画像に補正している 入力画像を真正面の画像(もしくは手動補正して)にして動かすと、切り分けしやすいのでは?コレの結果が正しい座標を返してくるなら結論は以下になると思います。 >GCV の 内部で画像に何かしらの補正をかけている。
namagon

2018/09/21 06:20

やはり補正をかけているが有力ですか、一旦問い合わせて返信があり次第追記します。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問