Apple Vision — не может распознать один номер как регион

Я хочу использовать 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 цифры + числа на белом фоне?


person AndrzejZ    schedule 06.01.2018    source источник
comment
Хороший вопрос, у меня тоже такая же проблема.   -  person Jagie    schedule 17.06.2018
comment
У меня похожая проблема. Это еще предстоит решить. stackoverflow.com/ вопросы/54282757/   -  person HumbleOne    schedule 27.03.2019
comment
Одиночные персонажи, как правило, читаются лучше, когда занимают больше места. Даже если один символ имеет больший размер шрифта, чем текст с несколькими символами, отдельные символы читаются для меня, когда они больше. Просто предположение: с одним символом недостаточно краев (или совпадающих краев, например, как результат преобразования ширины штриха), чтобы убедить алгоритм OCR в наличии символов.   -  person Rethunk    schedule 01.05.2021


Ответы (1)


Длинные символы по-прежнему являются проблемой для VNRecognizeTextRequest и VNDetectTextRectanglesRequest в XCode 12.5 и Swift 5.

Я видел, как VNDetectTextRectanglesRequest находит практически все отдельные слова на листе бумаги, но не может обнаружить отдельные символы [при обработке всего изображения]. Может помочь установка для свойства VNDetectTextRectanglesRequest.regionOfInterest меньшего региона.

Мне помогло то, что отдельные символы заняли большую часть интересующей области (ROI) для VNRecognizeTextRequest. Я протестировал одиночные символы на разной высоте, и стало ясно, что отдельные символы начинают читаться, как только они достигают определенного размера в пределах области интереса.

Для некоторых отдельных символов обнаружение происходит, когда ROI примерно в три раза больше ширины и в три раза больше высоты самого символа. Это довольно узкая область интересов. Правильное размещение — еще одна проблема, но тоже решаемая.

Если время обработки не является проблемой для вашего приложения, вы можете создать массив [CGRect], охватывающий область, предположительно содержащую одиночные символы.

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

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

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

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