You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VNRecognizeTextRequest的minimumTextHeight参数无效果问题咨询

为什么VNRecognizeTextRequest的minimumTextHeight参数不生效?

我用VNRecognizeTextRequest处理来自DocumentCameraViewController的图片文本识别,传入minimumTextHeight参数后,不管设0.9还是0.1,识别到的文本(包含大小字号)数量完全一致。我只想识别标题这类大字号文本,请问这个参数为啥不起作用?

我的代码如下:

fileprivate func recognizeText(from images: [CGImage], minimumTextHeight:Float) -> String {
    var entireRecognizedText = ""
    let recognizeTextRequest = VNRecognizeTextRequest { (request, error) in
        guard error == nil else { return }
        
        guard let observations = request.results as? [VNRecognizedTextObservation] else { return }
        
        let maximumRecognitionCandidates = 1
        for observation in observations {
            guard let candidate = observation.topCandidates(maximumRecognitionCandidates).first else { continue }
            entireRecognizedText += "\(candidate.string)\n"
            // show location of text in frame
            let stringRange = candidate.string.startIndex..<candidate.string.endIndex
            let boxObservation = try? candidate.boundingBox(for: stringRange)
            let boundingBox = boxObservation?.boundingBox ?? .zero
            print(candidate.string, boundingBox.origin.x, boundingBox.origin.y)
        }
    }
    recognizeTextRequest.revision = VNRecognizeTextRequestRevision3
    recognizeTextRequest.recognitionLevel = .accurate
    recognizeTextRequest.minimumTextHeight = minimumTextHeight
    recognizeTextRequest.recognitionLanguages = ["en-US", "en-GB", "de-DE"]
    
    for image in images {
        let requestHandler = VNImageRequestHandler(cgImage: image, options: [:])
        
        try? requestHandler.perform([recognizeTextRequest])
    }
    
    return entireRecognizedText
}

原因分析

  1. 参数是相对比例而非绝对像素:minimumTextHeight的取值是文本高度相对于整个图像高度的归一化比例,不是实际像素值。比如如果你的图像分辨率是3000x2000,0.1对应的实际高度是200像素,如果小字号文本高度刚好超过200像素,就会被识别出来,导致参数看起来没效果。
  2. 针对单个字符而非整行文本:在VNRecognizeTextRequestRevision3中,这个参数过滤的是单个字符的高度,不是整行文本的高度。如果小字号的单个字符高度达标,整行都会被保留。
  3. 图像自动缩放干扰计算:VNImageRequestHandler默认会对图像做预处理缩放,可能改变文本的相对高度比例,导致参数判断失效。

解决方案

  1. 正确计算归一化比例:先确定你要识别的最小文本高度(像素值),再除以图像的总高度得到比例。比如想要识别至少150像素高的文本,图像高度是2000,就设置minimumTextHeight = 150/2000 = 0.075。
  2. 手动过滤观测结果:如果参数自带的过滤逻辑不满足需求,在遍历VNRecognizedTextObservation时,手动计算文本的实际像素高度并过滤:
    for observation in observations {
        guard let candidate = observation.topCandidates(maximumRecognitionCandidates).first else { continue }
        // 计算文本实际高度
        let imageHeight = CGFloat(image.height)
        let textBoundingBox = try? candidate.boundingBox(for: candidate.string.startIndex..<candidate.string.endIndex)?.boundingBox ?? .zero
        let actualTextHeight = textBoundingBox.size.height * imageHeight
        // 过滤低于阈值的文本
        if actualTextHeight < 150 { // 这里150是你需要的最小像素高度
            continue
        }
        entireRecognizedText += "\(candidate.string)\n"
        print(candidate.string, textBoundingBox.origin.x, textBoundingBox.origin.y)
    }
    
  3. 关闭自动缩放:初始化VNImageRequestHandler时指定缩放因子为1.0,避免框架自动缩放影响高度计算:
    let options: [VNImageOption: Any] = [.scaleFactor: 1.0]
    let requestHandler = VNImageRequestHandler(cgImage: image, options: options)
    
  4. 调整识别模式:把recognitionLevel从.accurate改成.fast,后者会更倾向于合并文本块,更容易通过高度过滤整行大字号文本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 13:15:27