Почему GCP Vision API дает худшие результаты на Python, чем в его онлайн-демонстрации

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

На данный момент я экспериментирую со следующим изображением продукта: Почему GCP Vision API дает худшие результаты на Python, чем в его онлайн-демонстрации (разрешение 951 × 335)

Его торговая марка - Acuvue.

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

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, чтобы он работал правильно?

Меняется ли результат (каким-либо значимым образом) при использовании запроса DOCUMENT_TEXT_DETECTION вместо запроса TEXT_DETECTION? (пример)

jedwards 01.05.2018 15:56

Спасибо за ваш комментарий. Вы имеете в виду замену detect_text(file_name) на document_detect_text(file_name)? Это дает мне следующую ошибку: name 'document_detect_text' is not defined

Outcast 01.05.2018 16:08

И строку response = ..., и строку texts = ... следует изменить с помощью метода document_text_detection и атрибута full_text_annotation, как показано в примере, который я связал. Я надеюсь, что более надежный детектор найдет "Acuvue", но с уверенностью, которую стандартный детектор считает слишком низкой для включения.

jedwards 01.05.2018 16:11

Это очень хорошо! Теперь он возвращает длинный json, который в конце имеет следующее: text: "FOR ASTIGMATISM\n1-DAY ACUVUE\nMOIST\nWITH\nLACREON\342\204\242\n30 Lenses\nBRAND CONTACT LENSES\nUV BLOCKING\n". Однако мне интересно, что в нем означают эти числа `342 \ 204 \ 242`.

Outcast 01.05.2018 16:33

Так что вы можете записать ответ и, желательно, объяснить, что было неправильным в том, что я делал, а затем я отмечу его как правильное, если ничего не изменится.

Outcast 01.05.2018 16:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
5
798
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

The Vision API can detect and extract text from images. There are two annotation features that support OCR:

  • TEXT_DETECTION detects and extracts text from any image. For example, a photograph might contain a street sign or traffic sign. The JSON includes the entire extracted string, as well as individual words, and their bounding boxes.

  • DOCUMENT_TEXT_DETECTION also extracts text from an image, but the response is optimized for dense text and documents. The JSON includes page, block, paragraph, word, and break information.)

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

A DOCUMENT_TEXT_DETECTION response includes additional layout information, such as page, block, paragraph, word, and break information, along with confidence scores for each.

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

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

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

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

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

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

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

Другие вопросы по теме