EventKitでカレンダー・リマインダー連携を実装した流れで、以前Visionフレームワークでのテキスト認識を実装した経験を活かし、今度はバーコード・QRコードの読み取りに挑戦しました。
1. テキスト認識と同じ設定で使えると思っていた
最初、以前のテキスト認識のコードを流用すればそのままバーコードも読み取れると思い込んでいました。
let request = VNDetectBarcodesRequest()
リクエスト自体はこのように簡単に作れるのですが、実行してみると特定の種類のバーコードしか検出されず、意図したQRコードが認識されないことがありました。調べてみると、symbologiesプロパティで認識対象のシンボロジー(QRコード、JANコードなど)を指定でき、指定しない場合はデフォルトの対象範囲に限定される仕組みだと分かりました。
2. 連続フレームで同じコードを何度も処理してしまった
カメラ映像から連続的にバーコードを検出する実装にしたところ、同じコードを読み取るたびに何度も後続の処理(画面遷移など)が呼ばれてしまいました。
不足していた設定:
直前に処理済みの値と同じ場合はスキップする判定
Visionのリクエスト自体には「同じ値を連続で検出しない」機能はなく、呼び出し側で直前に処理した値を保持し、同じ値であれば処理をスキップするロジックを自分で実装する必要があると分かりました。
3. 画面の一部だけを読み取り範囲にしたかったが全体を読んでしまった
QRコードリーダーのUIとして画面中央に読み取り枠を表示していたのですが、実際には枠の外にあるコードまで読み取られてしまいました。
request.regionOfInterest = CGRect(x: 0.25, y: 0.25, width: 0.5, height: 0.5)
regionOfInterestを設定することで、画像全体ではなく指定した範囲内だけを認識対象にできることが分かりました。表示している読み取り枠の位置とこの範囲を一致させることで、意図した見た目通りの挙動になりました。
4. 暗い場所での認識精度の低さに戸惑った
明るい室内では問題なく認識できていたのに、少し暗い場所で試すと全く反応しなくなることがありました。
確認したこと:
カメラのライト(トーチ)機能をオンにするボタンの追加
Vision自体の設定でどうにかなる問題ではなく、そもそも画像の入力品質(明るさ)に依存する部分が大きいと理解しました。カメラのトーチ(ライト)をオンにするボタンをUIに追加し、暗所でもユーザー自身で明るさを確保できるようにすることで対応しました。
まとめ
symbologiesで認識対象のバーコード種類を明示的に指定しないと、意図したコードが検出されないことがある- 連続検出時の重複処理は、Vision側ではなく呼び出し側で直前の値との比較により防ぐ必要がある
regionOfInterestで読み取り範囲を絞ることで、UIの読み取り枠と実際の認識範囲を一致させられる- 暗所での認識精度はVisionの設定ではなく入力画像の明るさに依存するため、トーチ機能などで補う必要がある
同じVisionフレームワークでも、対象がテキストかバーコードかによって考慮すべき点が異なると実感した実装でした。
本記事は生成AI(Claude)を活用して執筆・編集しています。内容は実体験に基づき、執筆者本人が確認・監修しています。


コメント