Vision, VNDetectTextRectanglesRequest - не может распознать одно число как регион

Я хочу использовать VNDetectTextRectanglesRequest из каркаса Vision для обнаружения областей на изображении, содержащем только один символ, число "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" на белом фоне также не обнаруживается.

Почему в моем случае Vision API обнаруживает только 3 цифры + цифры на белом фоне?

1 ответ

Эта проблема сохраняется в XCode 12.5 и Swift 5: все еще могут быть трудности с чтением отдельных символов.

Что сработало для меня, так это то, что отдельные персонажи занимают большую часть экрана. Я тестировал отдельные символы на различные высоты, и стало ясно , что отдельные символы будут начать читать , как только они достигли определенного размера, и что минимальная высота для одного символа должна быть заметно больше , чем текст высота небольших , но читаемое слово из трех и более символов.

Одинокий символ может быть вдвое больше шрифта, чем читаемый текст с меньшими символами.

Я подозреваю, что алгоритм выполняет начальную проверку содержания краев, плотности краев и / или характеристик изображения, напоминающих штрихи. Как бы то ни было, он работает быстро, поэтому я не думаю, что это так сложно.

Чтобы узнать больше об обнаружении штриха, поищите сообщения SO и статьи о преобразовании ширины штриха. Также это: https://www.microsoft.com/en-us/research/publication/detecting-text-in-natural-scenes-with-stroke-width-transform/

Есть несколько приемов, позволяющих обойти эту проблему. Некоторые из этих приемов неприятны, но для конкретного приложения они могут того стоить.

  • Используйте фильтр масштабирования, чтобы увеличить изображение перед его обработкой. Это может гарантировать, что отдельные символы будут достаточно большими для чтения. (Для CIFilters очень удобный ресурс https://cifilter.io/)
  • Если вы можете обойтись без использования интересующей области для VNRecognizeTextRequest, создайте увеличенное изображение только для этой интересующей области.
  • Выполните несколько проходов по вашему изображению. Сначала запустите OCR для полного изображения. Затем получите ограничивающие рамки для прочитанных слов. Найдите подозрительные промежутки между коробками. Создайте фрагменты изображений областей подозрительных пробелов, увеличьте их масштаб и снова попробуйте OCR.
  • Попробуйте использовать фильтр морфологии, чтобы увидеть, помогает ли увеличение толщины текста идентификации. Вы должны использовать CIMorphologyMaximum или CIMorphologyMinimum, в зависимости от того, темный ли текст на светлом или светлый на темном.
  • Используйте Tesseract как резервную копию. (https://www.seemuapps.com/swift-optical-character-recognition-tutorial)
Другие вопросы по тегам