ARKitでのAR表示を実装した流れで、次は写真に写った文字を読み取ってテキストとして扱いたいと考え、Visionフレームワークによるテキスト認識(OCR)に挑戦しました。
1. 撮影した写真をそのまま渡せば認識できると思っていた
最初、カメラで撮った写真をそのままVNRecognizeTextRequestに渡せば、写っている文字を高い精度で認識してくれるものだと思い込んでいました。
let request = VNRecognizeTextRequest()
request.recognitionLevel = .accurate
実際にはrecognitionLevelの設定次第で認識精度と処理速度が大きく変わり、デフォルトのままではぼやけた文字や小さい文字の認識精度が思ったより低いことが分かりました。精度重視の.accurateに切り替えたことで認識率は改善しましたが、その分処理時間が延びるというトレードオフも実感しました。
2. 日本語がそのまま認識できると思い込んでいた
英語の文章では問題なく認識できていたのですが、日本語の文字を含む写真を試したところ、文字化けのような結果や認識漏れが目立ちました。
request.recognitionLanguages = ["ja-JP", "en-US"]
recognitionLanguagesで認識対象の言語を明示的に指定していなかったことが原因でした。指定しない場合は英語が優先される挙動になっており、日本語の文字を認識させるには対象言語にja-JPを含める必要があると気づくまで、正しく認識できない原因が分からず時間を使ってしまいました。
3. 認識結果の並び順を勘違いしていた
複数行にわたるテキストを認識させたところ、返ってきた結果の順序が画面上の見た目の並びと一致しておらず、テキストの意味がおかしくなってしまいました。
発生した問題:
認識結果の配列順が読み上げ順(上から下)と一致しない
Visionの認識結果はそのままでは信頼度順や検出順で返ってくることがあり、画面上の位置情報(バウンディングボックス)を使って自分でソートし直す必要がありました。認識結果をそのまま連結するだけでは、意図した文章の並びにならないと学びました。
4. 低コントラストな文字で認識率が大きく落ちた
背景と文字の色が近い写真(明るい背景に薄い色の文字など)を認識させたところ、認識率が目に見えて落ちてしまいました。
改善前後の違い:
コントラストの低い元画像 → 認識率が低い
事前にコントラストを強調した画像 → 認識率が改善
Vision自体にコントラストを補正する機能はないため、認識前処理として画像のコントラストを強調するフィルタを一段挟むことで、認識率が明らかに改善しました。Visionに渡す前の画像の質が、認識精度に直結すると実感しました。
まとめ
recognitionLevelは精度と速度のトレードオフ。用途に応じて.accurateと.fastを使い分ける- 日本語を認識させるには
recognitionLanguagesにja-JPを明示的に含める必要がある - 認識結果の並び順は保証されないため、バウンディングボックスの位置情報を使って自分でソートする
- 低コントラストな画像は認識率が落ちる。事前にコントラストを強調する前処理が効果的
文字を読み取ること自体は数行で実装できても、実用に耐える精度に持っていくには画像の前処理や結果の後処理まで含めた調整が欠かせないと実感した実装でした。
次は、Core Motionでの歩数・活動データの取得について分かったことをまとめます。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント