Как отправить изображение Base64 для обнаружения меток API Google Cloud Vision в Ruby?

Привет, я создаю программу на Ruby для создания атрибутов alt для изображений на веб-странице. Я очищаю страницу для изображений, а затем отправляю их src, другими словами, URL-адрес, в google-cloud-vision для обнаружения меток и других методов Cloud Vision. На одно изображение уходит около 2-6 секунд. Мне интересно, есть ли способ уменьшить время отклика. Сначала я использовал TinyPNG для сжатия изображений. Cloud Vision был немного быстрее, но время, затраченное на сжатие, с лихвой перевесило улучшение. Как я могу улучшить время отклика? Перечислю несколько идей.

1) Поскольку мы отправляем URL-адрес в Google Cloud, Google Cloud требуется время, чтобы получить ответ, то есть от img_src, прежде чем он сможет даже проанализировать изображение. Быстрее ли отправить изображение в кодировке base64? Какая самая быстрая форма для отправки (или, на самом деле, для получения Google) изображения?

cloud_vision = Google::Cloud::Vision.new project: PROJECT_ID
@vision = cloud_vision.image(@file_name)
@vision.labels #or @vision.web, etc.

2) Мой текущий код для обнаружения этикеток. Первый вопрос: быстрее ли отправить запрос JSON, чем вызывать методы Ruby (label или web) в проекте Google Cloud? Если да, следует ли ограничивать ответы? Ярлыки с показателем достоверности менее 0,6 не очень помогают. Ускоряет ли это время записи / обработки изображения?

Открыт для любых предложений о том, как ускорить время отклика от Cloud Vision.


person aaronbnb    schedule 12.07.2017    source источник
comment
Пожалуйста, оставьте отзыв на предоставленный ответ. У вас это сработало или нет? Если нет, то почему?   -  person karnesJ.R    schedule 12.07.2017
comment
Вам лучше сохранить изображение в файл, а затем отправить его - в библиотеке ruby ​​Cloud Vision есть способ для этого. Если вы отправляете изображение как объект String, вы потребляете для него оперативную память, и я не удивлюсь, если библиотека Net :: HTTP все равно преобразует полезную нагрузку в временный файл, если он достаточно большой.   -  person Nakilon    schedule 13.07.2017


Ответы (2)


TL; DR - вы можете воспользоваться поддержкой пакетной обработки в API аннотаций для Cloud Vision.

Более длинная версия

Google Cloud Vision API поддерживает пакетную обработку нескольких запросов за один вызов images:annotate API. Существуют также эти ограничения, которые применяются для Cloud Vision:

  • Максимум 16 изображений на запрос
  • Максимум 4 МБ на изображение
  • Общий размер запроса не более 8 МБ.

Вы можете уменьшить количество запросов, разделив их по 16 пакетов за раз (при условии, что вы не превысите какие-либо ограничения размера изображения в запросе):

#!/usr/bin/env ruby

require "google/cloud/vision"

image_paths = [
  ...
  "./wakeupcat.jpg",
  "./cat_meme_1.jpg",
  "./cat_meme_2.jpg",
  ...
]

vision = Google::Cloud::Vision.new
length = image_paths.length

start = 0
request_count = 0
while start < length do
  last = [start + 15, length - 1].min
  current_image_paths = image_paths[start..last]
  printf "Sending %d images in the request. start: %d last: %d\n", current_image_paths.length, start, last
  result = vision.annotate *current_image_paths, labels: 1
  printf "Result: %s\n", result
  start += 16
  request_count += 1
end

printf "Made %d requests\n", request_count
person Tuxdude    schedule 16.07.2017

Итак, вы используете Ruby для очистки некоторых изображений со страницы, а затем отправляете изображение в Google, да?

Почему вы можете не захотеть кодировать изображение в формате base64:

  • Безголовое сканирование становится более интенсивным в сети. Вы должны загрузить изображение, чтобы затем обработать его.
  • Теперь вам также нужно позаботиться о добавлении в процесс кодирования base64
  • Потенциальные проблемы с хранением, если вы не просто храните изображение в памяти (и если вы это сделаете, отладка станет несколько более сложной.

Почему вы можете захотеть кодировать изображение в формате base64:

  • Изображение не является общедоступным
  • Вы все равно должны сохранить изображение

После того, как вы взвесили варианты, если вы все еще хотите получить изображение в base64, вот как это сделать:

require 'base64'
Base64.encode(image_binary)

Это действительно так просто.

Но как мне получить это изображение в двоичном формате?

require 'curb'
# This line is an example and is not intended to be valid
img_binary = Curl::Easy.perform("http://www.imgur.com/sample_image.png").body_str

Как мне отправить это в Google?

У Google есть довольно подробное описание этого процесса здесь: Сделайте запрос Vision API в JSON.

Если вы не можете щелкнуть по нему (или вам лень), я предоставил копию и вставку с нулевым контекстом того, как должно выглядеть тело запроса для их API, здесь:

request_body_json = {
  "requests":[
    {
      "image":{
        "content":"/9j/7QBEUGhvdG9...image contents...eYxxxzj/Coa6Bax//Z"
      },
      "features":[
        {
          "type":"LABEL_DETECTION",
          "maxResults":1
        }
      ]
    }
  ]
}

Итак, теперь мы знаем, как должен выглядеть запрос в теле. Если вы уже отправляете img_src в запросе POST, это очень просто:

require 'base64'
require 'curb'
requests = []
for image in array_of_image_urls
  img_binary = Curl::Easy.perform(image).body_str
  image_in_base64 = Base64.encode(image_binary)
  requests << { "image" => { "content" : image_in_base64 }, "imageContext" => "<OPTIONAL: SEE REFERENCE LINK>", "features" => [ {"type" => "LABEL_DETECTION", "maxResults" => 1 }]}
end

# Now just POST requests.to_json with your Authorization and such (You did read the reference right?)

Поиграйте с форматированием хэша и значениями, если это необходимо. Это общая идея, и это лучшее, что я могу дать вам, когда ваш вопрос СУПЕР расплывчатый.

person karnesJ.R    schedule 12.07.2017
comment
Спасибо за пространное объяснение. Действительно ценю это; Меня просто волнует скорость. Нет смысла кодировать изображение base64. Поскольку я открыл веб-страницу с изображением, казалось, что его можно было бы быстрее закодировать, преобразовав его в строку, чтобы Google не пришлось открывать эту страницу. В любом случае, я исправил свой исходный пост. Был бы признателен за ваши мысли. - person aaronbnb; 14.07.2017
comment
@aaronbnb Вы хотите, чтобы Google как можно быстрее выполнял alt-теги? Итак, зачем вам заставлять их сервис получать данные ввода-вывода на изображении? Отправка изображения в Base64 - это изображение, и службе не нужно извлекать само изображение. Возможно, это не будет большим улучшением, но это будет что-то. Библиотека ruby ​​просто отправляет отформатированные запросы в Google. Нет никаких улучшений в использовании ручного JSON вместо него. Ограничение тегов может быть недопустимой стратегией, поскольку я не знаю, как работает процессор изображений, но я предполагаю, что ограничение тегов просто ограничивает вывод, который вы получаете обратно. - person karnesJ.R; 04.08.2017