Почему GCP Vision API возвращает худшие результаты в python, чем в его онлайн-демонстрации - PullRequest
0 голосов
/ 01 мая 2018

Я написал базовый скрипт на Python для вызова и использования GCP Vision API. Моя цель - отправить изображение продукта на него и извлечь (с помощью OCR) слова, написанные на этом поле. У меня есть предопределенный список брендов, поэтому я могу искать в возвращенном тексте из API бренд и определять, что это такое.

Мой скрипт на Python выглядит следующим образом:

import  io
from google.cloud import vision
from google.cloud.vision import types
import os
import cv2
import numpy as np

os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "**************************"


def detect_text(file):
    """Detects text in the file."""
    client = vision.ImageAnnotatorClient()

    with io.open(file, 'rb') as image_file:
        content = image_file.read()

    image = types.Image(content=content)

    response = client.text_detection(image=image)
    texts = response.text_annotations
    print('Texts:')

    for text in texts:
        print('\n"{}"'.format(text.description))

        vertices = (['({},{})'.format(vertex.x, vertex.y)
                    for vertex in text.bounding_poly.vertices])

        print('bounds: {}'.format(','.join(vertices)))


file_name = "Image.jpg"
img = cv2.imread(file_name)

detect_text(file_name)

Сейчас я экспериментирую со следующим изображением продукта: enter image description here (разрешение 951 × 335)

Бренд Acuvue.

Проблема заключается в следующем. Когда я тестирую онлайн-демонстрацию API GCP Cloud Vision, я получаю следующий текстовый результат для этого изображения:

FOR ASTIGMATISM 1-DAY ACUVUE MOIST WITH LACREON™ 30 Lenses BRAND CONTACT LENSES UV BLOCKING

(Результат json для этого возвращает все вышеупомянутые слова, включая слово Acuvue, которое имеет для меня значение, но json слишком длинный, чтобы разместить его здесь)

Таким образом, онлайн-демонстрация довольно хорошо обнаруживает текст на продукте и, по крайней мере, точно определяет слово Acuvue (которое является брендом). Однако, когда я вызываю тот же API в моем скрипте Python с тем же изображением, я получаю следующий результат:

Texts:

"1.DAY
FOR ASTIGMATISM
WITH
LACREONTM
MOIS
30 Lenses
BRAND CONTACT LENSES
UV BLOCKING
"
bounds: (221,101),(887,101),(887,284),(221,284)

"1.DAY"
bounds: (221,101),(312,101),(312,125),(221,125)

"FOR"
bounds: (622,107),(657,107),(657,119),(622,119)

"ASTIGMATISM"
bounds: (664,107),(788,107),(788,119),(664,119)

"WITH"
bounds: (614,136),(647,136),(647,145),(614,145)

"LACREONTM"
bounds: (600,151),(711,146),(712,161),(601,166)

"MOIS"
bounds: (378,162),(525,153),(528,200),(381,209)

"30"
bounds: (614,177),(629,178),(629,188),(614,187)

"Lenses"
bounds: (634,178),(677,180),(677,189),(634,187)

"BRAND"
bounds: (361,210),(418,210),(418,218),(361,218)

"CONTACT"
bounds: (427,209),(505,209),(505,218),(427,218)

"LENSES"
bounds: (514,209),(576,209),(576,218),(514,218)

"UV"
bounds: (805,274),(823,274),(823,284),(805,284)

"BLOCKING"
bounds: (827,276),(887,276),(887,284),(827,284)

Но это вообще не обнаруживает слово "Acuvue", как в демо !!

Почему это происходит?

Можно ли что-то исправить в моем скрипте на python, чтобы он работал правильно?

1 Ответ

0 голосов
/ 01 мая 2018

Из документов :

Vision API может обнаруживать и извлекать текст из изображений. Есть две функции аннотации, которые поддерживают OCR:

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

  • DOCUMENT_TEXT_DETECTION также извлекает текст из изображения, но ответ оптимизирован для плотного текста и документов. JSON включает информацию о странице, блоке, абзаце, слове и разрыве.)

Я надеялся, что веб-API фактически использует последнее, а затем фильтрует результаты на основе достоверности.

Ответ DOCUMENT_TEXT_DETECTION включает дополнительную информацию о макете, такую ​​как информация о странице, блоке, абзаце, слове и разрыве, а также доверительные оценки для каждого.

Во всяком случае, я надеялся (и мой опыт таков), что последний метод будет «стараться» найти все строки.

Я не думаю, что вы делали что-то "неправильно". Есть только два параллельных метода обнаружения. Один (DOCUMENT_TEXT_DETECTION) является более интенсивным, оптимизирован для документов (вероятно, для выпрямленных, выровненных и равномерно распределенных линий) и дает больше информации, которая может быть ненужной для некоторых приложений.

Поэтому я предложил вам изменить ваш код, следуя примеру Python здесь .

Наконец, я предполагаю, что \342\204\242, о котором вы спрашиваете, - это экранированные восьмеричные значения, соответствующие символам utf-8, которые, как он считает, были найдены при попытке идентифицировать символ ™.

Если вы используете следующий фрагмент:

b = b"\342\204\242"
s = b.decode('utf8')
print(s)

Вы будете рады видеть, что он печатает ™.

...