You need to enable JavaScript to run this app. Swift 中使用.accurate精度的文本识别出现倒置读取(0606识别为9090)问题
优惠活动
大模型
产品
解决方案
定价
更多

Swift 中使用.accurate精度的文本识别出现倒置读取(0606识别为9090)问题

Vision文本识别出现倒置结果的修复方案

问题根因

0606被识别为9090的异常,核心原因是送入Vision框架的图片未做方向校正:
Vision框架默认以「原点在左上角、无旋转」的图片为识别基准,但UIImage自带的方向元数据经常和实际像素方向不一致——你直接取image.cgImage传给识别器时,框架拿到的是带180度旋转的像素数据,就会把倒立的文本做正向识别。这种方向错位刚好匹配你遇到的识别结果:正向的0606整体倒置180度后,数字6会变为9,同时阅读顺序完全反转,最终被识别为9090。.accurate模式下框架对这类方向偏差的容错能力反而比.fast模式更差,不会自动帮你修正方向错位的问题。

具体修改步骤

  • 第一步:给UIImage增加方向校正能力,把所有方向的图片统一转为up方向的标准像素图
    加入扩展方法实现方向归一化:
    extension UIImage {
        func normalizedCGImage() -> CGImage? {
            guard imageOrientation != .up else { return cgImage }
            
            var transform = CGAffineTransform.identity
            switch imageOrientation {
            case .down, .downMirrored:
                transform = transform.translatedBy(x: size.width, y: size.height).rotated(by: .pi)
            case .left, .leftMirrored:
                transform = transform.translatedBy(x: size.width, y: 0).rotated(by: .pi/2)
            case .right, .rightMirrored:
                transform = transform.translatedBy(x: 0, y: size.height).rotated(by: -.pi/2)
            default: break
            }
            
            guard let sourceCGImage = cgImage, let colorSpace = sourceCGImage.colorSpace else { return nil }
            let context = CGContext(
                data: nil,
                width: Int(size.width),
                height: Int(size.height),
                bitsPerComponent: sourceCGImage.bitsPerComponent,
                bytesPerRow: 0,
                space: colorSpace,
                bitmapInfo: sourceCGImage.bitmapInfo.rawValue
            )
            context?.concatenate(transform)
            
            let drawRect: CGRect
            switch imageOrientation {
            case .left, .leftMirrored, .right, .rightMirrored:
                drawRect = CGRect(x: 0, y: 0, width: size.height, height: size.width)
            default:
                drawRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
            }
            context?.draw(sourceCGImage, in: drawRect)
            return context?.makeImage()
        }
    }
    
  • 第二步:替换原代码里直接取cgImage的逻辑
    原代码中直接传入image.cgImage的部分,换成调用校正方法得到的标准化图片:
    DispatchQueue.global(qos: .userInitiated).async {
        // 替换原来的 guard let img = image.cgImage ...
        guard let normalizedImage = image.normalizedCGImage() else { fatalError("Missing valid image to scan") }
        let handler = VNImageRequestHandler(cgImage: normalizedImage, options: [:])
        try? handler.perform([request])
    }
    
  • 第三步:补充识别请求的必要配置,减少识别偏差
    在设置识别精度的位置追加配置,避免框架做不必要的结果篡改:
    request.recognitionLevel = .accurate
    request.usesLanguageCorrection = false // 识别编码/数字场景下关闭语言校正,避免框架自动修改数字结果
    

额外代码优化点

  • 你原代码中在识别闭包外定义textString变量的逻辑存在问题:识别闭包是异步回调,多个识别结果会覆盖同一个外部变量,要把textString的初始化移到识别回调内部,按观察结果的实际坐标顺序拼接,不要靠循环顺序直接覆盖赋值
  • 如果是从相机采集的识别场景,要同步确认相机输出帧的方向和当前设备方向匹配,不要把横置、倒置的帧直接送入识别流程

内容的提问来源于stack exchange,提问作者Omar Rayyan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.07 20:24:04