苹果视觉 - 无法将单个数字识别为区域

9

我想要使用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”会被检测为一个具有文本的区域。对于两位数的数字,“22”在白色背景上也无法被检测到。

为什么视觉API在我的情况下只能检测到白色背景上的3位以上数字?


1
好问题,我也有同样的问题。 - Jagie
我遇到了类似的问题。它还没有得到解决。 - HumbleOne
1
单个字符在占据更多的空间时往往更易阅读。即使单个字符的字体大小比具有多个字符的文本大,当它们更大时,单个字符对我来说更容易阅读。只是猜测:对于单个字符,没有足够的边缘(或匹配的边缘,也许像笔画宽度变换的输出)来说服OCR算法存在字符。 - Rethunk
1个回答

2
长字符在XCode 12.5和Swift 5中的VNRecognizeTextRequest和VNDetectTextRectanglesRequest仍然存在问题。
我看到VNDetectTextRectanglesRequest可以找到纸张上几乎所有的单词,但在处理整个图像时无法检测到孤立字符。将VNDetectTextRectanglesRequest.regionOfInterest属性设置为较小的区域可能有所帮助。
对于我来说有效的方法是使单个字符在VNRecognizeTextRequest的兴趣区域(ROI)中占据更大的空间。我测试了多种高度的单个字符,明显单个字符在ROI内达到一定大小后就会开始识别。
对于某些单个字符,当ROI大约是字符本身宽度和高度的三倍时,检测似乎发生了。这是一个相当紧密的感兴趣区域。将其正确放置是另一个问题,但也可以解决。
如果处理时间对您的应用程序没有关系,您可以创建一个跨越可能包含孤立字符的区域的数组[CGRect]。
我的怀疑是,当VNRecognizeTextRequest对边缘内容、边缘密度和/或类似笔画的图像特征进行初始检查时,如果没有找到足够的候选项,它会提前退出。这个初始检查可能只是一个嵌入式的VNDetectTextRectanglesRequest。无论初始检查是什么,它都运行得很快,所以我不认为它很复杂。
要了解更多有关查找字符的笔画检测信息,请搜索SO帖子和文章,以了解Stroke Width Transform。还有这个:https://www.microsoft.com/en-us/research/publication/detecting-text-in-natural-scenes-with-stroke-width-transform/。SWT旨在处理“自然”图像,例如户外看到的文本。
有一些绕过这个问题的技巧。其中一些技巧可能不太好,但对于特定应用程序来说,它们可能是值得的。
  • 创建一组小的感兴趣区域(ROIs)的网格。逐个ROI运行文本请求。
  • 作为VNDetectTextRectanglesRequest的廉价替代品,寻找具有边缘内容的图像区域,表明可能存在单个字符。如果没有其他内容,这可以帮助忽略没有边缘内容的区域。
  • 尝试使用缩放滤镜在处理图像之前对其进行缩放。这可以确保单个字符足够大以便读取。(对于CIFilters,一个非常方便的资源是https://cifilter.io/
  • 对您的图像运行多次处理。首先在整个图像上运行OCR。然后获取已读取单词的边界框。搜索框之间可疑的空隙。在可疑的空白区域上运行小的ROIs网格。
  • 使用Tesseract作为备份。(https://www.seemuapps.com/swift-optical-character-recognition-tutorial

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接