近所のパン屋のレシートは、紙の上では完璧でした。 108円と198円で小計306円、消費税24円を足して合計330円。 どこにも矛盾がありません。 それをアプリで撮ったら、品目がひとつも取れませんでした。 3つの数字のどれひとつ、読んだ文字を品目と金額に分ける部分まで届いていなかったのです。
レシートを撮って割り勘するアプリを作っています。 読み取りがうまくいかなかったとき、ユーザーが「読み取りを報告」を押すと、 そのときの生の読み取り結果がこちらに届く仕組みにしてあります。 その報告が5枚たまりました。5枚とも、正確には解析できていませんでした。
うまくいかなかった理由が、想像していたのと違いました。 正直に言えば、精度の問題だと思っていました。字が薄いとか、影が入ったとか。 実際に起きていたのは別のことです。
5枚のうち4枚は、いまは正しく読めます。 残る1枚は、読めない理由が分かったうえで読めないままです。 何が起きていて、何をどう直したのかを書きます。
いまお使いの方向けに先に書いておくと、読み取りがずれたときは 確認画面でその場で直せます。金額も品名も編集でき、 読み落とされた品目は「+ 品目を追加」から足せます。 撮り方のコツはよくある質問にまとめてあります。 この記事は、その裏で何が起きているのかの話です。
パン屋のレシートで何が起きていたか、読み取り結果をそのまま並べます。
| 紙に印刷されていた字 | 読み取られた字 | 結果 |
|---|---|---|
| 108※ | 108%% | 金額として認識されず |
| 198※ | 198章 | 金額として認識されず |
| 330 | 33O | 合計が取れず |
※ は軽減税率の対象を示す記号です。
これが %% になったり 章 になったりする。
そして合計の最後の 0 が、数字のゼロではなく英字の O として返ってきていました。
人間の目には、どれも読み間違えようがありません。
でもスキャナは字を「認識」しているのではなく、
形の近いものの中から一番それらしいものを返しているだけです。
0 と O は形が近い。※ と % も近い。
それだけの話です。
ここに落とし穴があります。
「英字の O が来たらゼロに直す」で解決したくなりますが、
同じ報告の中にタクシーのレシートがあって、
印字された電話番号のゼロが、先頭も末尾も英字の O として返ってきていました。
全部ゼロに直すと、この電話番号がまるごと金額の候補として立ち上がってきます。
O をゼロに直す修復は、前後が数字であるときだけ効かせる必要がありました。
字が化けるのは、まだ分かりやすいほうでした。 残りの報告で起きていたのは、正しく読めているのに、買ったものではないという問題です。
| レシート | 何を品目として拾ったか |
|---|---|
| タクシー | 受付番号 No.1566。運賃と同じ列に印字されていた |
| コンビニ | 合計行そのもの。ラベルの 計 が 言 と 十 に割れて、合計だと分からなくなった |
| コンビニ | 呼び出し番号 No. 107 |
| 美容室 | 支払い方法の欄。VISA という文字と、崩れた「支払い方法」が、それぞれ金額を連れて品目になった |
レシートには、買ったものと同じ見た目で、買っていないものがたくさん印刷されています。 受付番号、呼び出し番号、電話番号、登録番号、会員番号。 どれも数字で、多くは金額と同じ列に並びます。
いちばん厄介だったのはコンビニの1枚です。
合計 というラベルの 計 が縦に割れて 言 と 十 になり、
合計行が合計だと認識されなくなりました。
その結果、合計行が「もう1つ買ったもの」として品目リストに並びました。
2品しか買っていないレシートが、3品になったわけです。
5枚とも回帰テストに固定して、品目と金額に分ける部分を直しました。 いまの結果です。
| レシート | 報告時 | いま |
|---|---|---|
| パン屋 | 品目 0 | 2品・合計330円 |
| タクシー | 1566円の品目 | 運賃1件 |
| コンビニ(合計行) | 3品 | 2品 |
| コンビニ(呼び出し番号) | 2品 | 1品 |
| 美容室 | 3品 | 1品・合計は取れず 未解決 |
美容室の1枚だけ、まだ正しく読めません。 品目は取れるようになりましたが、合計が0のままです。 理由は単純で、このレシートには合計のラベルが印刷されていないからです。 「合計」も「お会計」も無い紙から合計を取るには、 印字された金額の関係を推測するしかありません。 それは読み取りの修正ではなく別の設計なので、 いまは「読めないレシート」として記録に残してあります。
直せない1枚をテストに残しておくのは、気分の良いものではありません。 ただ、消してしまうと次に同じ紙が来たときに、また同じところで驚くことになります。 直っていないことを、直っていない形で残すほうが結局は早い、というのが今回の結論でした。
最初の、読んだ文字を品目と金額に分ける部分は、レシートに「理想的な字」が印刷されている前提で書かれていました。
合計 と書いてあれば合計、数字が並んでいれば金額。
その前提が、実物の前で崩れました。
いま入っているのは、こういう考え方です。
合計 は 合 言十 でも合計として扱うレシートは、規格の決まった帳票ではありません。 店ごとに違う紙に、店ごとに違う並びで、店ごとに違う記号が印刷されています。 その上をスキャナが通ると、印刷されたとおりの字は返ってきません。 当たり前のことなのですが、実物の報告が5枚たまるまで、 自分は理想的な字を前提にコードを書いていました。
パシャワリは、レシートを撮ると品目と金額を読み取り、 1枚の中で品目ごとに「どちらが何割」を変えられる ふたり向けの割り勘アプリです。この記事の修正は、そのまま実装に入っています。 読み取りは端末の中だけで行い、レシートの写真はどこにも送りません。
App Store と Google Play から、無料(広告が表示されます)で入れられます。
この記事のとおり、読めなかったレシートは、直したときか合計が合わないときに確認画面のいちばん下に出る「読み取りを報告」から送れます。 1枚届くたびに、読める紙が増えます。
アプリを見る この記事を相手に送る