我想使用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位+数字?
答案 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 旨在处理“自然”图像,例如在户外看到的文本。
有一些技巧可以解决这个问题。其中一些黑客行为令人不快,但对于特定应用程序而言,它们可能是值得的。