1
1

SwiftのImageAnalyzerで画像内の縦書き文章を認識する(縦書きOCR)

Last updated at Posted at 2024-05-27

結論

画像内に日本語の文章しかないなら、ImageAnalyzerを使えばおけです!

sample.swift
func recognizeVerticalText(image: UIImage) async -> String {
        var recognizedText = ""
        guard #available(iOS 16.0, *) else { return recognizedText } // iOS16以上必須
        let analyzer = ImageAnalyzer()
        let configuration = ImageAnalyzer.Configuration(.text)
        do {
            let analysis = try await analyzer.analyze(image, configuration: configuration)
            recognizedText = analysis.transcript
        } catch {
            // error時の処理
        }
        return recognizedText
    }
    

注意

日本語と英語が混じった横書きの文章にはなぜかImageAnalyzerでは認識できません!代わりに王道(?)のVNRecognizeTextRequestを使います!

sample.swift
func recognizeHorizontalText(image: UIImage?) async -> String {
        var recognizedText = ""
        guard let cgImage = image?.cgImage else { return recognizedText }
        let handler = VNImageRequestHandler(cgImage: cgImage, options: [:])
        let request = VNRecognizeTextRequest { request, err in
            guard let observations = request.results as? [VNRecognizedTextObservation], err == nil else { return }
            let texts = observations.compactMap({
                $0.topCandidates(1).first?.string
            }).joined(separator: ", ")
            recognizedText = texts
        }
        request.recognitionLanguages = ["ja-JP", "en-US"] // 認識する言語の指定
        request.recognitionLevel = VNRequestTextRecognitionLevel.accurate // 認識速度重視ならfast、正確さ重視ならaccurate
        request.usesLanguageCorrection = true
        
        do {
            try handler.perform([request])
        } catch {
            // error時の処理
        }
        return recognizedText
    }

なぜImageAnalyzerでは日本語と英語が混じった横書きを認識できないのか?

いろんな種類の画像で検証してみましたが、原因不明です。画像内に英文しかない時に認識できるのはもちろん、日本語文章しかない時に縦書きと横書きの同時認識は可能でした。また、Configuration下にlocalesという値を見つけたんですが、もしかしたら、このlocalesがVNRecognizeTextRequestでいうrecognitionLanguagesのような役割を果たしているのかもしれません。なので、localesを正しくいじいじすれば解決しそうな気がします!知らんけど

対抗策

自分はUISwitch(SwiftUIではToggle)で、縦書きを認識するか横書きを認識するかあらかじめユーザーさんに決めてもらい、上記二つのメソッドをスイッチのオンオフで条件分岐して使っています。しかし、ユーザーさんの手間が増えてしまうのでできれば避けたいです。recognitionLanguagesのようにImageAnalyzerでも言語の指定方法があるのか、ある場合どうコードを書けば良いのか、ご存知の方いらっしゃったら教えていただけると助かります!

余談

オーディオブック作成アプリ「パシャリス」をAppStoreで公開してたんですけど、今までは参考書とかノートとか横書きの文章しか認識できなかったため、かなり欠陥アプリだったんですよねwwwでも、これで縦書きの本とかでもオーディオブック化できるようになり、より幅広い分野での音声学習が可能になりました!ImageAnalyzerの解説を上げてくださった参考記事の方には感謝しかありません!届けこの思い!ではでは!

ImageAnalyzerの参考記事

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1