Vision,VNDetectTextRectanglesRequest - 无法将单个数字识别为区域

时间:2018-01-06 11:47:53

标签: ios swift mobile ocr apple-vision

我想使用Vision框架中的VNDetectTextRectanglesRequest来检测图像中只包含一个字符(数字'9')和白色背景的区域。我正在使用以下代码执行此操作:

 private func performTextDetection() {
    let textRequest = VNDetectTextRectanglesRequest(completionHandler: self.detectTextHandler)
    textRequest.reportCharacterBoxes = true
    textRequest.preferBackgroundProcessing = false

    let handler = VNImageRequestHandler(cgImage: loadedImage.cgImage!, options: [:])

    DispatchQueue.global(qos: .userInteractive).async {
        do {
            try handler.perform([textRequest])
        } catch {
            print ("Error")
        }
    }
}

func detectTextHandler(request: VNRequest, error: Error?) {
    guard let observations = request.results, !observations.isEmpty else {
        fatalError("no results")
    }

    print("there is result")
}

我得到的观察结果数量为0,但是如果我在黑色背景上提供带有文本“123”的图像,则“123”被检测为带有文本的区域。对于2位数字也会出现所述问题,白色背景上的“22”也未被检测到。

为什么Vision API在我的情况下只检测白色背景上的3位+数字?

1 个答案:

答案 0 :(得分:0)

长字符仍然是 XCode 12.5 和 Swift 5 中 VNRecognizeTextRequest 和 VNDetectTextRectanglesRequest 的问题。

我已经看到 VNDetectTextRectanglesRequest 几乎可以找到一张纸上的所有单个单词,但 [在处理整个图像时] 无法检测到单独的字符。将属性 VNDetectTextRectanglesRequest.regionOfInterest 设置为较小的区域可能会有所帮助。

对我有用的是让单个字符占据更多 VNRecognizeTextRequest 的感兴趣区域 (ROI)。我在各种高度测试了单个字符,很明显单个字符在达到 ROI 内的特定大小时开始阅读。

对于某些单个字符,当 ROI 大约是字符本身宽度的三倍和高度的三倍时,似乎会发生检测。这是一个相当紧密的兴趣区域。正确放置它是另一个问题,但也是可以解决的。

如果处理时间不是您的应用程序的问题,您可以创建一个数组 [CGRect],跨越怀疑包含单独字符的区域。

我怀疑,当 VNRecognizeTextRequest 对边缘内容、边缘密度和/或类似于笔画的图像特征执行初始检查时,如果没有找到足够的候选者,它会提前退出。该初始检查可能只是一个嵌入的 VNDetectTextRectanglesRequest。不管最初的检查是什么,它运行得很快,所以我认为它没有那么复杂。

有关笔画检测以查找字符的更多信息,请搜索有关笔画宽度变换的 SO 帖子和文章。还有这个:https://www.microsoft.com/en-us/research/publication/detecting-text-in-natural-scenes-with-stroke-width-transform/。 SWT 旨在处理“自然”图像,例如在户外看到的文本。

有一些技巧可以解决这个问题。其中一些黑客行为令人不快,但对于特定应用程序而言,它们可能是值得的。

  • 创建一个由感兴趣的小区域 (ROI) 组成的网格。在一个又一个 ROI 上运行文本请求。
  • 作为 VNDetectTextRectanglesRequest 的廉价替代品,寻找具有表明可能存在单个字符的边缘内容的图像区域。如果不出意外,这有助于忽略没有边缘内容的区域。
  • 在处理图像之前尝试使用缩放过滤器放大图像。这可以确保单个字符足够大以供阅读。 (对于 CIFilters,一个非常方便的资源是 https://cifilter.io/
  • 在您的图像上运行多次。首先,在完整图像上运行 OCR。然后获取已阅读单词的边界框。搜索盒子之间的可疑间隙。在可疑的空白区域上运行小 ROI 网格。
  • 使用 Tesseract 作为备份。 (https://www.seemuapps.com/swift-optical-character-recognition-tutorial)