
Чего ожидать
Этот урок покажет разработчикам, как очень быстро создать приложение Visual AI. Мы напишем программу Python, которая обнаружит продукты в холодильнике и проверит рекламный буклет в супермаркете на наличие скидок. Предварительный опыт работы с компьютерным зрением не требуется.
Мы будем использовать VisionAgent, генеративный конструктор приложений ИИ, который помогает разработчикам — даже тем, у кого нет опыта работы с компьютерным зрением — легко и эффективно создавать визуальные приложения. Прежде чем углубляться в детали, давайте на минутку вспомним проблемы, с которыми инженеры сталкивались при реализации задач зрения в своих приложениях.
Фон
Компьютерное зрение — сложная область изучения из-за огромных проблем в обучении машин интерпретировать и понимать визуальную информацию так, как это делают люди. Для большинства случаев использования необходимо одновременно решать несколько сложных задач.
Во-первых, визуальное восприятие включает обработку невероятно плотной информации. Одно изображение содержит миллионы пикселей, и каждый пиксель представляет собой нюансированный цвет, текстуру и пространственные отношения, которые должны быть точно интерпретированы алгоритмами для быстрого различения объектов, распознавания шаблонов и извлечения значимой информации из этих массивов пикселей. Во-вторых, объекты могут выглядеть по-разному в зависимости от освещения, угла, частичного препятствия, расстояния и фонового контекста. Система компьютерного зрения должна быть достаточно надежной, чтобы распознавать стул как стул, независимо от того, рассматривается ли он спереди, сбоку, частично скрыт или в разных условиях освещения. В-третьих, семантическое понимание выходит за рамки простого обнаружения объектов. Расширенное компьютерное зрение не просто идентифицирует объекты, но и понимает их отношения, потенциальные действия и контекстное значение. Например, это будет означать распознавание не только того, что изображение содержит человека и велосипед, но и понимание того, что человек, вероятно, готовится ехать на велосипеде.
Следовательно, исследования и разработки в области компьютерного зрения последовательно опирались на междисциплинарные подходы, интегрируя такие строгие области, как математика, компьютерные науки, оптика, обработка сигналов и изображений, когнитивная наука, статистика и машинное обучение (МО) и др. Помимо технического мастерства, построение эффективных систем компьютерного зрения требует интегративной методологии, которая синтезирует идеи из этих сложных и взаимосвязанных дисциплин, требуя глубоких экспериментальных знаний и совместного решения проблем.
Несмотря на наличие мощных инструментов, таких как OpenCV и большие мультимодальные модели на основе Vision transformer1, разработчикам все равно придется изучать основы компьютерного зрения и знакомиться с соответствующими SDK и моделями программирования, чтобы эффективно интегрировать компьютерное зрение в доменно-ориентированные приложения. Кроме того, организациям также необходимо будет инвестировать в значительные вычислительные ресурсы, а также потенциально получить большие наборы данных для обучения. Тем не менее, благодаря достижениям в области МО, это быстро меняется, что позволит нам очень легко реализовать наше приложение для обнаружения и пополнения овощей!
Давайте перейдем к практической части этого руководства. Вы можете продолжить, взаимодействуя с VisionAgent через его веб-интерфейс и просматривая модули Python по ссылкам, указанным в руководстве. Весь репозиторий кода также будет предоставлен в общий доступ.
Файл README.md содержит инструкции по установке (для Python 3.10 или выше).
Разработка приложения «Что в твоем холодильнике?»
Мы напишем программу Python, которая обнаруживает продукты в холодильнике и проверяет рекламный буклет супермаркета на наличие скидок. Поэтому мы будем работать с двумя изображениями, показанными ниже:
- Изображение продуктов в холодильнике; и
- Изображение листовки супермаркета, рекламирующей доступные скидки на продукты.

Рисунок 1: Изображение различных продуктов, включая овощи, в холодильнике.

Рисунок 2: Изображение рекламного проспекта супермаркета, на котором указаны цены со скидкой на некоторые продукты2.
Давайте используем схему, которая разбивает проблему на две отдельные задачи, а затем объединяет их результаты в качестве третьей задачи:
- Первая задача — обнаружить продукты на изображении холодильника (рисунок 1) и вернуть словарь, ключами которого являются названия овощей (например, «помидоры», «лук» и т. д.), а значения — их соответствующие количества.
- Вторая задача — определить цену продажи для каждого продукта в рекламном буклете со специальными предложениями (рисунок 2) и вернуть словарь, ключами которого являются названия овощей (например, «помидоры», «лук» и т. д.), а значениями — соответствующие им цены со скидкой.
- При таком подходе мы могли бы ожидать, что наборы ключей обоих словарей будут перекрываться, что позволило бы нам определить, какие продукты в холодильнике доступны по распродаже.
Введение в VisionAgent
VisionAgent упрощает разработчикам без глубокого компьютерного зрения или опыта работы с ИИ решение задач зрения, предоставляя удобный интерфейс для простой загрузки изображения или видео и генерации визуального кода ИИ из текстовой подсказки. Все, что им нужно сделать, это поиграть с сгенерированным кодом, чтобы получить некоторую интуицию, чтобы сосредоточиться на желаемом поведении, затем протестировать его, возможно, настроить некоторые пороговые значения и выполнить рефакторинг кода, чтобы интегрировать модули непосредственно в свой производственный рабочий процесс.
Внутри VisionAgent используются фреймворки агентов, конструкции планирования и рассуждения, а также LLM с вызовом инструментов, среди прочих методов генерации кода для решения вашей задачи компьютерного зрения.
Использование VisionAgent для создания нашего приложения
Мы будем взаимодействовать с VisionAgent через его веб-интерфейс, поскольку он интуитивно понятен и прост в использовании. Входные данные — это image3 и текстовая подсказка, а выходные данные — это информация, полученная из изображения в соответствии с инструкциями, данными в подсказке. Важно, что также предоставляется код Python, который был выполнен VisionAgent для генерации выходных данных. Мы сохраним модули Python, сгенерированные для обеих задач, и адаптируем их к потребностям нашего приложения.
Таким образом, для каждой задачи мы выполним следующие шаги:
- Откройте веб-интерфейс VisionAgent;
- Загрузите изображение и внимательно изучите его, чтобы получить представление о его «атмосфере»;
- Придумайте подсказку, которая заставит модель вернуть это содержимое, и вставьте подсказку в пользовательский интерфейс; повторяйте подсказку, пока вывод не будет соответствовать ожидаемому (или близким к ожидаемому).
- Нажмите на вкладку «Код» справа и загрузите код Python на наш локальный компьютер.
- Запустите код на нашей локальной машине и проведите необходимое тестирование и исправление ошибок.
Если вы просмотрите шаги, описанные выше, первые четыре, скорее всего, будут очевидны. Однако шаг 5 может вызвать вопрос о его цели и необходимости. В конце концов, разве мы не ожидаем, что агент, реализация которого опирается на мощные LMM (большие мультимодальные модели) и LLM (большие языковые модели), вернет «правильный ответ», который «просто работает», который мы могли бы подключить? На самом деле, ситуация более тонкая, поэтому, пожалуйста, продолжайте читать, и мы скоро доберемся до этого.
Теперь мы готовы выполнить эти шаги для каждой из двух задач.
Задача 1: Классификация продуктов в холодильнике
Начнем с открытия веб-интерфейса VisionAgent и загрузки изображения с рисунка 1 в соответствующее поле. Затем мы изучим то, что отображается на экране. Мы видим салат ромэн, разное количество моркови, помидоров, сельдерея, грибов и лука; а также кое-что еще.
Теперь мы хотим, чтобы VisionAgent классифицировал содержимое холодильника и выдал нам код, который он придумал и выполнил для этого задания. Для этой задачи классификации выбрана следующая подсказка4:
Определите и классифицируйте различные типы овощей, которые можно увидеть в холодильнике, например, салат, морковь и помидоры. Сосредоточьтесь на распознавании каждого овоща и классификации их по типу.
Через несколько секунд на экране появится результат:
Я проанализировал изображение и идентифицировал овощи в холодильнике. Вот краткое изложение того, что я нашел: Овощи, найденные в холодильнике: — Морковь: 2 — Помидоры: 2 — Сельдерей: 4 — Грибы: 1 Я также создал изображение с ограничивающими рамками вокруг обнаруженных овощей, которое было сохранено как «vegetables_detected.png». Теперь вы можете просмотреть это изображение, чтобы увидеть визуальное представление обнаруженных овощей.
Кроме того, в правой части пользовательского интерфейса мы видим следующий вывод:
[{'vegetable_counts': {'lettuce': 0, 'carrots': 2, 'tomatoes': 2, 'celery': 4, 'mushrooms': 1, 'green onions': 0}, 'summary': 'В холодильнике найдены овощи:n- Морковь: 2n- Помидоры: 2n- Сельдерей: 4n- Грибы: 1n', 'image_with_boxes': <массив ограничивающих рамок>,dtype=uint8)}]
Быстрая проверка выходных данных агента в отношении рисунка 1 показывает, что агент не обнаружил салат ромэн. Если бы салат был запутан, то мы могли бы принять это упущение. Но салат распознается однозначно. Следовательно, мы устраним неполадки и исправим код для его обнаружения.
Чтобы увидеть сгенерированный код, щелкните вкладку «Код» в правой части веб-интерфейса VisionAgent (рядом с вкладкой «Результат»), а затем стандартный значок загрузки, чтобы сохранить модуль Python на локальном компьютере (или просмотрите файл vegetable_classifier.py, размещенный здесь для удобства).
Далее мы протестируем этот модуль, выявим неполадки и исправим проблему с отсутствующим салатом, а также найдем возможности улучшить качество и надежность кода.
Чтобы проверить, раскомментируйте строку
# результат = identify_vegetables('/home/user/gcrgkLJ_RefrigeratorContents11142024as01.png')
(строка 54), замените сгенерированный аргумент путем на локальном компьютере к изображению на рисунке 1 (например, «workspace/RefrigeratorContents11142024as01.png») и добавьте строку print(result['vegetable_counts'])ниже, чтобы увидеть результат. Затем выполните:
% Python овощ_классификатор.py
в оболочке терминала и убедитесь, что вывод соответствует содержимому словаря «vegetable_counts» выше.
Чтобы выяснить причину отсутствия салата, полезно открыть vegetable_classifier.py в вашем любимом редакторе и сделать быстрый обзор кода. Просматривая метод identify_vegetables(), мы можем суммировать его основную функциональность в виде следующего псевдокода:
- Импортируйте необходимые пакеты и библиотеки.
- Загрузите изображение в память.
- Составьте список основных меток классов, состоящий из распространенных названий овощей, и объедините их в подсказку.
- Вызовите метод owl_v2_image() с изображением, подсказкой и параметром допуска box_threshold в качестве аргументов, при этом значение box_threshold должно быть установлено равным 0,3 (константа).
- Проанализируйте результат, выбрав овощи, показатель обнаружения которых превышает пороговое значение 0,3 (то же постоянное значение, что и на предыдущем шаге).
Чтобы проверить нашу гипотезу о том, что box_threshold может влиять на чувствительность обнаружения, мы углубляемся в импортированный модуль vision_agent.tools и прокручиваем вниз до определения метода owl_v2_image(). Хотя OWLv25 является очень мощной моделью обнаружения объектов компьютерного зрения6, для нас важно то, что box_threshold играет ключевую роль и имеет значение по умолчанию 0,1 (на строку box_threshold: float = 0,10, в модуле «tools.py»).
Замена значений 0,3 на 0,1 для box_threshold во всем vegetable_classifier.py и его повторный запуск подтверждают, что салат обнаружен! Таким образом, теперь мы можем формально исправить наш метод identify_vegetables(), включив box_threshold (со значением по умолчанию 0,1) в качестве аргумента и используя его вместо констант с плавающей точкой. Пока мы это делаем, мы также можем удалить неиспользуемые импорты, сделать код более эффективным (заменив инициализацию словаря на однострочный, использующий defaultdict) и добавить некоторую базовую обработку ошибок. Эти типы улучшений требуют минимальных усилий, но они могут принести значительную пользу проекту за счет снижения затрат на обслуживание. Для справки предоставляется пересмотренная версия vegetable_classifier.py, запуск которой дает ожидаемые результаты.
Задача 2: Определение цен со скидкой на продукты питания в листовке
Продолжаем, создавая новый чат в веб-интерфейсе VisionAgent и загружая изображение с рисунка 2 (проспект супермаркета). Мы можем сделать мысленную заметку, что салат и помидоры входят в число продаваемых продуктов. Вспоминая содержимое нашего холодильника, эта информация будет полезна для целей тестирования.
Далее мы предлагаем VisionAgent отсканировать изображение и найти предложения по образцу овощей:
Найдите овощи на этом изображении (например, салат, морковь, помидоры и т. д.) и запишите их цены. Верните результаты в формате JSON.
Агент приступает к работе и возвращает следующий результат:
Выполнение кода Выполнение кода Вот овощи, найденные на изображении, вместе с их ценами, отсортированными в алфавитном порядке: [ { «name»: «Брюссельская капуста — 1 фунт», «price»: «$3.99 / фунт» }, { «name»: «Огурец длинный хот-хаус английский», «price»: «$2.99 / шт» }, { «name»: «Сердечки расфасованные — 3 шт», «price»: «$1.33 / шт» }, { «name»: «Тепличный большой помидор.», «price»: «$2.69 / шт -$3.59» }, { «name»: «Тепличный большой помидор.», «price»: «$2.99 / фунт» }, { «name»: «Салат айсберг», «price»: «$2.99 / шт» }, { «name»: «Органический огурец», «price»: «$1.79 / шт» }, { «name»: «Органический огурец», «цена»: «$1,79 / шт.» }, { «название»: «Расфасованный — 16 унций», «цена»: «$2,99 / фунт» }, { «название»: «Желтый кабачок «Крукнек»», «цена»: «$2,99 / фунт» } ] Хотите ли вы что-то еще, чтобы я сделал с этими данными, или у вас есть другие вопросы по поводу изображения?
Первое, что мы замечаем, это то, что «Выполнение кода.» появляется дважды. Это связано с тем, что VisionAgent использует цикл, содержащий этап рассуждения, план выполнения и этап суждения с обратной связью, который повторяется до тех пор, пока система не сочтет свои результаты оптимальными. Остальное — список овощей и их продажных цен в формате JSON. Вывод JSON также показан справа:
['[n {n «name»: «approx»,n «price»: «$3.99 / ea»n },n {n «name»: «Тепличный большой помидор.»,n «price»: «$2.69 / ea -$3.59″n },n {n «name»: «SNAP»,n «price»: «$2.99 / ea»n },n {n «name»: «SNAP»,n «price»: «$2.99″n },n {n «name»: «Тепличный большой помидор.»,n «price»: «($2.99 / фунт)»n },n {n «name»: «Брюссельская капуста — 1 фунт»,n «price»: «($3.99 / фунт)»n },n {n «name»: «Огурец Long Hot House English»,n «цена»: «($2.99 / шт.)»n },n {n «название»: «Расфасованная — 16 унций»,n «цена»: «($2.99 / фунт)»n },n {n «название»: «SNAP»,n «цена»: «$2.99″n },n {n «название»: «Органический огурец»,n «цена»: «$1.79/шт.»n },n {n «название»: «SNAP»,n «цена»: «$3.99″n },n {n «название»: «приблизительно»,n «цена»: «$2.00 / шт.»n },n {n «название»: «Салат Айсберг»,n «цена»: «($2.99 / шт.)»n },n {n «название»: «Органический огурец»,n «цена»: «($1.79 / шт.)»n },n {n «название»: «Желтая тыква «Крукнек»»,n «цена»: «($2.99 / фунт)»n },n {n «название»: «Сердечки расфасованные — 3 шт.»,n «цена»: «($1.33 / шт.)»n }n]']
Второе наблюдение заключается в том, что некоторые элементы повторяются (например, «Тепличный большой помидор» и «Органический огурец»), что указывает на то, что где-то в сгенерированном коде, вероятно, есть ошибка.
Чтобы начать устранение неполадок, нажмите на вкладку «Код», а затем на значок загрузки, чтобы сохранить модуль Python на локальном компьютере (или просмотрите файл vegetable_price_detector.py, предоставленный для удобства).
Чтобы протестировать модуль, мы раскомментируем вызов find_vegetables_and_prices() и заменим его аргумент на путь на локальном компьютере к изображению на рисунке 2 (например, «workspace/SafewayFlyer11142024as0.png»), а также раскомментируем строку print(result) ниже, чтобы увидеть результат, напечатанный на стандартном выводе. Затем выполните:
% python овощ_цена_детектор.py
в оболочке терминала и убедитесь, что вывод соответствует приведенному выше в пользовательском интерфейсе VisionAgent.
Проверив поведение кода, сгенерированного агентом в качестве базового, мы переходим к обзору кода. Прокручивая find_vegetables_and_prices() в vegetable_price_detector.py, мы сразу же узнаем знакомую операцию обнаружения объектов с помощью метода owl_v2_image(). Кроме того, изображение обрабатывается операцией OCR (расшифровывается как оптическое распознавание символов) с использованием метода ocr(), также импортированного из модуля vision_agent.tools, для извлечения текста, содержащего цены продажи. Затем алгоритм вычисляет евклидовы расстояния между ограничивающими прямоугольниками продуктов и цен. Пары овощ-цена, имеющие наименьшее расстояние, считаются правильными совпадениями. Однако, как упоминалось ранее, в реализации этого критерия остановки есть ошибка, из-за которой дублированные цены связываются с данным овощем.
Исправление оказалось очень простым. Нет необходимости вести список цен на каждый овощ. Все, что нам нужно сделать, это установить цену, если существует минимальное расстояние между ограничивающим прямоугольником овоща и прямоугольником цены (т. е. results[veg_name] = mostliest_price).
После проверки исправления этой ошибки мы снова параметризуем find_vegetables_and_prices() с помощью box_threshold (снова используя значение по умолчанию 0,1) и возвращаем словарь с очищенными ценами вместо объекта JSON, поскольку формат словаря лучше подходит для наших целей.
Мы также преобразуем «tomato» во множественное число, чтобы читать «tomatoes», чтобы ключи словарей, возвращаемые обоими модулями, используемыми в нашем приложении, были нормализованы. С этими изменениями исправленная версия vegetable_price_detector.py предоставляется для справки и проверки ее поведения.
Обратите внимание, что мы могли бы сделать vegetable_price_detector.py более эффективным, исключив операцию квадратного корня, поскольку операция возведения в квадрат неотрицательна и увеличивается, а нас интересуют только относительные сравнения, а не фактическое расстояние. Мы приглашаем читателей изучить эту и другие возможности улучшения, пока мы переходим к обсуждению последней части: объединению двух модулей, которые мы получили с помощью VisionAgent, для построения нашего приложения.
Задача 3: Интеграция обоих скриптов в приложение
Оба наших скрипта возвращают словари, ключами которых являются названия овощей. Оба словаря могут иметь общие ключи по замыслу. Таким образом, теперь мы можем написать программу main(), которая анализирует изображения и выводит названия продуктов, продающихся по распродаже, и их цену.
Программа main() предоставляется в модуле Refill_veggies.py. Мы используем библиотеку Python argparse для обработки передачи двух аргументов, «—img_fridge_contents» и «—img_deals_flyer», в любом порядке. Затем эти изображения загружаются из каталога WORKSPACE, указанного переменной среды.
Мы импортируем identify_vegetables() и find_vegetables_and_prices() из соответствующих модулей, которые мы разработали с помощью VisionAgent для предыдущих задач, и выполняем их для получения словарей vegetable_counts и vegetable_deals соответственно. Затем мы проходим по словарю vegetable_counts и печатаем цену продажи для овощей, которые также находятся в словаре vegetable_deals. Вот вывод:
У вас в холодильнике 6 сельдерея. Сегодня в Safeway нет скидок на сельдерей. У вас в холодильнике 1 салат. СКИДКА!!! Сегодня в Safeway можно купить больше салата за $3.99. У вас в холодильнике 3 помидора. СКИДКА!!! Сегодня в Safeway можно купить больше помидоров за $2.69. У вас в холодильнике 4 гриба. Сегодня в Safeway нет скидок на грибы. У вас в холодильнике 10 морковок. Сегодня в Safeway нет скидок на морковь. У вас в холодильнике 2 зеленых лука. Сегодня в Safeway нет скидок на зеленый лук.
Теперь, когда у нас есть список покупок, мы можем отправиться в Safeway!
Заключение
До недавнего времени разработка приложений компьютерного зрения требовала экспертных знаний в различных научных и технологических дисциплинах, что делало ее сложной и дорогостоящей задачей. Сегодня, используя агентские рабочие процессы, разработчики могут напрямую создавать решения ИИ, адаптированные к их конкретным операционным потребностям, используя такие инструменты, как VisionAgent, что значительно сокращает время и технические барьеры для внедрения. Таким образом, нам потребовалось всего несколько часов, чтобы написать приложение, которое распознает овощи в холодильнике и проверяет рекламные листовки супермаркетов на предмет скидок на эти товары. Попробуйте создать приложения с поддержкой зрения на VisionAgent для себя и… не забывайте есть овощи!
¹Например, модели открытого веса CLIP, BLIP, Qwen-VL, LLaVA; а также некоторые коммерческие модели.
² Это изображение защищено авторским правом © Safeway, Inc.
³Для других случаев использования в качестве входных данных также принимаются видеоклипы продолжительностью до 30 секунд.
⁴Вам предлагается поэкспериментировать с различными подсказками и выбрать наиболее подходящую для вашего случая использования.
⁵OWL означает «Open-World Localization» (локализация в открытом мире) (для получения дополнительной информации см. https://huggingface.co/docs/transformers/en/model_doc/owlvit).
⁶См. https://arxiv.org/abs/2306.09683 для оригинальной исследовательской статьи и https://huggingface.co/docs/transformers/en/model_doc/owlv2 для общей информации и примеров.
Источник: landing.ai



























