検証編
前回まで
前回の記事ではレシートの左右で回転角度が異なるときに別で回転するソリューションを提案しました。
前回の記事はこちらからチェックできます!
概要
前回提案したソリューションが正しいかどうかを実際のデータをもとに計算で確認していきたいと思います。結果がうまくいかなかった際にはその改善も随時行います。そして検証に使用するデータは次に示すレシート画像から取得したJSONデータから抜粋します。
データを利用して計算してみる
今回使用するデータは先ほど示した Text 要素を使用していきます。まず一番大きな要素は
「セブン-イレブン」なのでこの左の縦辺の傾きLangle
と中心座標$ (𝑙𝐶_𝑥,𝑙𝐶_𝑦) $、右の縦辺の傾きRangle
と中心座標$ (𝑟𝐶_𝑥, 𝑟𝐶_𝑦) $を求めます。下記の図を参考にしてください。
$$ lC_y = \frac{347+421}{2}=384 $$
$$ Langle = \frac{347-421}{187-179}=-9.25 $$
$$ rC_x = \frac{228+221}{2}=224.5 $$
$$ rC_y = \frac{351+424}{2}=387.5 $$
$$ Rangle = \frac{351-424}{228-221}=-10.429 $$
次に、傾きを利用して回転角を求めます。前回示していた式は
$$ \theta = 90-\tan^{-1}(angle) $$
でしたが、今回 angle
がマイナスになっており 90
度に合わせようとすると 170
度ほど回転
させてしまいました。つまり行のデータがさかさまになってしまったので、これを防止しま
す。また C#
の Math
ライブラリで Atan
を使用すると、返り値は弧度法であることが分かりました。これらを考慮して式を次のように変更しました。
$$
\theta = (\frac{\pi}{2}-|\tan^{-1}(angle)|)*\frac{angle}{|angle|}
$$
これにより$ \theta_{left} $と$ \theta_{right}$の値は
$$ \theta_{left} = -0.1077 $$
$$ \theta_{right} = -0.0956 $$
と計算できます。この$ \theta $とそれぞれの中心座標で、セブン-イレブン
の BoundingBox
を回転させます。
$$ \hat{x} = C_x + (x-C_x)*\cos\theta - (y-C_y) * \sin\theta $$
$$ \hat{y} = C_y + (x-C_x)*\sin\theta + (y-C_y) * \cos\theta $$
$ \theta_{left} $と$ \theta_{right} $、$ (𝑙𝐶_𝑥,𝑙𝐶_𝑦) $と$ (𝑙𝐶_𝑥,𝑙𝐶_𝑦) $を利用して四頂点を回転結果がこちらになります。
この二通りで計算した要素中心座標からy
座標の差div
を計算します。$ \theta_{left} $で得られた要素の中心y
座標をLeft
、$ \theta_{right} $で得られた要素の中心y
座標をRight
として計算をすると
$$ div = Left - Right = -4.23 $$
となりました。Left
のほうが大きいと+
、Right
のほうが大きいと-
になります。
最後になりますが、セブン-イレブン
の要素から得られた回転角度とdiv
を利用してお
や釣
、¥3000
の要素の移動を行います。今回は$ \theta_{left} $ と$ \theta_{right}$を有効活用して行いますが、将来的には要素それぞれで補正を行うと思います。
左側にはお
と釣
、右側に¥3000
があるので¥3000
の要素のy
座標にはdiv
を足します。
その結果の座標が次になります。
この結果と元のBoundingBox
の座標を比較すると、縦の座標右側の要素と近づいたと思いますが、要素がより傾いてしまっているのが確認できます。
今回使用した画像は、比較的きれいに撮影できているにもかかわらず、この傾きの変化が起こってしまっているので、要素は個々に回転角度を設定する方がよさそうですね。
さいごに
次回以降ではこのプログラムを作成し、行の判別の正当性を検討します。
また、これらを利用したOCRは、LINEからどなたでも無料でご利用いただけますので、
ぜひ試してください!
また、OCRのでも体験がこちらのページからできます!
次の記事。コードを作成しました。