Привет, Хабр!

Меня зовут Денис. Хочу рассказать о том, как мы разрабатывали и внедряли кассы самообслуживания для столовых и фудкортов. 

Краткое содержание: 

  • почему распознавать еду сложно (но можно);

  • где мы ожидали получить проблемы, и где они были на самом деле;

  • почему не нужно помогать кассиру делать свою работу;

  • сколько котлет нужно сфоткать для уверенного распознавания;

  • бунт кассиров, бессмысленный и беспощадный;

  • какие проблемы создает товароведу касса самообслуживания;

  • и еще много интересного!

Поехали.

Часть первая. «Давайте автоматизируем кассу!»

Сегодня, когда ИИ разве что кофе в постель не приносит, эта история кажется немного наивной. Но тогда мы действительно думали, что идея хорошая. В 2020 году большинство столовых вне зависимости от ценовой категории имели кассовую зону с тетенькой той или иной степени суровости, задача которой заключалась в пропикивании блюд на подносе.

В больших столовых на крупных промышленных предприятиях, в которых мы тогда регулярно внедряли и настраивали POS-системы, проблема медленных касс была весьма ощутимой. Порой буквально. Потому что очередь работяг или офисных работников, пришедших на обед, компенсировала низкую скорость своего передвижения высокой плотностью размещения в очереди людей.

Вот примерно такие очереди.
Вот примерно такие очереди.

Ну вот же! Давайте сделаем ускорение обслуживания на кассе. Автоматизируем пропикивание и тем самым облегчим работу кассиров. О разработке замены кассирам речь, конечно, не шла. Лишь об ускорении их работы. Заодно разгрузим зал и увеличим пропускную способность столовой.

Мы запартнерились с компанией SkalaVision, ребята взяли на себя матчасть по OCR. На нас же осталась разработка POS-систем, интеграция с оборудованием и кастомная доводка решения по месту.

Работать должно было так. Гость ставит поднос под стойку с камерой на кассе. Кассир нажимает на экране POS-системы кнопку «Распознать». Происходит магия OCR и на экране появляются все блюда, которые система узнала. Кассир вручную вносит корректировки, если нужно, и пробивает чек.

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

И вот здесь нас поджидал первый сюрприз. Мы рассчитывали, что сможем быстро забить в базу обучения все меню и выкатить систему на прод. В реальных же условиях обучение растягивалось на 3-4 недели. Почему?

  • Цикличность меню. В общепите существует ротация блюд. Это нужно не только для того, чтобы разнообразить ассортимент и порадовать клиентов, но и для оптимизации расходования продуктов. Поэтому недельное меню варьируется.

  • Внешний вид блюд зависит от смены. Несмотря на технологические карты, в которых вроде бы расписано приготовление блюда, салат «Весенний» одной смены отличается от такого же салата другой. Чуть иначе порезано, немного другая форма котлеты, пюрешку размазывают по тарелке слева направо, а не справа налево — и вот уже нейросеть запинается.

  • Схожие блюда. Борщ красный и свекольник тоже красный. Даже потребитель не всегда отличит одно от другого, а нейросетка путается постоянно.

Это котлеты.
Это котлеты.
И это котлеты.
И это котлеты.
И это тоже.
И это тоже.

Все это требовало увеличения количества сэмплов, а значит сроки обучения неприлично увеличивались.

Однако хуже другое: проблема не столько техническая, сколько организационная. Как любой бизнес, общепит стремится увеличить прибыль и уменьшить расходы. Поэтому свекольник — это не просто еще один красный суп. Это способ с пользой применить остатки свеклы после борща и тем самым снизить расходы.

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

Что с этим можно сделать? Мы придумали два варианта.

  1. Разносить визуально схожие блюда по разным сервисам подачи (утро-день-вечер) или по разным дням, а нейросети объяснять, что борщ бывает, например, по вторникам и четвергам, а свекольник только в среду. Это решение требует некоторой реорганизации технологических процессов в столовой и естественным образом не реализуется. Нужно продавливать управляющих.

  2. Оставить в системе распознавание для бизнес-ланчей. На некоторых предприятиях мы пошли этим путем. Суть в том, что бизнес-ланч имеет фиксированный набор блюд. Поэтому, даже если система ошибется и неверно идентифицирует борщ, точность распознавания бизнес-ланча в целом останется высокой и он добавится в чек правильно. Фактически, мы добились 100% точности в распознавании бизнес-ланчей.

Идентификация Борна борща.
Идентификация Борна борща.

Результаты: все пошло не так

Напомню: по задумке, наша система должна была упростить и ускорить работу кассиров в столовой. В реальности кассы стали работать в 2-3 раза медленнее! При работе в архаичном ручном режиме обслуживание одного клиента занимало у кассира от 20 до 30 секунд в среднем. А с помощью нашей суперсовременной OCR-системы — до полутора минут. Это фиаско.

Причина, если ее сформулировать одним предложением, заключалась в том, что мы совершенно не учли особенности работы кассира. Как истинные технари-энтузиасты мы бросились решать проблему, которой на самом деле не существовало.

Ожидание.
Ожидание.
Реальность.
Реальность.

Во-первых, обычно POS-система всегда выводит одни и те же блюда на одном и том же месте экрана. Поэтому опытный кассир может даже вслепую, глядя лишь на поднос, вводить в чек блюда. Это быстро.

В нашей же системе на экране отображались лишь распознанные блюда. Их порядок каждый раз был разным. Нужно смотреть на экран, а это медленно.

Во-вторых, из-за ошибок распознавания, мало просто смотреть на экран, нужно смотреть внимательно, чтобы убедиться, что в списке есть компот, а котлета — именно биточек, а не бифштекс. Это еще медленнее.

Частично удалось решить с помощью реорганизации экранного пространства (подогнали layout под быстрые пальчики кассирш), и цветового кодирования.

С бизнес-ланчами дело обстояло намного лучше. Но и здесь не обошлось без сюрпризов. Например, как-то раз на раздаче закончились рубленные бифштексы и повара стали в бизнес-ланч класть обычную котлету. А на кассе в чек заносится бифштекс! Потому что бизнес-ланч распознается целиком и подразумевает именно бифштекс. Возникает пересортица.

Выводы по первой части

Не ошибается тот, кто ничего не делает. Мы выяснили, что помогать кассиру делать свою работу не надо. Лучше просто не мешать. Но хотелось бы это знать до того, как мы разработали и внедрили наше «ускорение» на нескольких крупных предприятиях. Конечно, далеко не на всех из них все было настолько плохо, а на многих даже было хорошо. Но это другая история.

Правильно было бы провести детальную аналитику и кастдев потенциальных пользователей решения, изучив их потребности и реальные, а не выдуманные нами проблемы. Потом как следует обкатать в тестовом режиме и… сразу перейти к правильному варианту решения. А именно:…

Часть вторая: «Кассир не нужен!»

Не можешь победить — возглавь. В смысле, а почему бы не сделать кассиром саму POS-систему? Так наше решение по распознаванию еды эволюционировало в терминалы самообслуживания.

Задумка была проста как вареная картошка. Ставим терминал, в который занесено все сегодняшнее меню. Клиент подходит к терминалу, ставит поднос под камеру и нажимает кнопку «Распознать», а затем тут же и оплачивает банковской картой или картой сотрудника.

Как это выглядит у Сбера. Рандомное фото из интернета.
Как это выглядит у Сбера. Рандомное фото из интернета.

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

Почему комплексные обеды, думаю, уже понятно. В отличие от заведений фастфуда, где терминал самообслуживания прекрасно работает при заказе бургеров и картошки фри, в столовой все иначе.

  • Меню столовых длиннее и чаще меняется. Следовательно, пользователь будет испытывать те же трудности, что и кассиры: блюда раз от раза будут оказываться в разных местах.

  • Бургер достаточно сфоткать красиво один раз. Красивые картинки для всех видов котлет отснять сложнее.

  • Система распознавания работала на тот момент все же не идеально.

Похожее зарубежное решение.
Похожее зарубежное решение.

При этом плюсы перехода к кассам самообслуживания очевидны. Кассиров в общепит вообще довольно сложно найти: работа муторная, низкооплачиваемая и непрестижная. Кассиру при этом нужно платить, плюс есть факторы недобросовестной работы. А терминалы занимают меньше места, их можно поставить больше, следовательно, пропускная способность столовой увеличится.

Результаты: намного лучше

В этот раз тестовые прогоны показали очень хорошие результаты. Мы установили один терминал рядом с кассовой зоной. Т.е. часть клиентов шла через кассира, часть через терминал. Оказалось, что скорость обслуживания примерно одинаковая. При том, что кассир вводит блюда быстро, а клиент — не торопясь. Это успех!

Проблемы, конечно, тоже были.

С технической стороны были подтормаживания кассы из-за процесса распознавания. Обработка потока на слабеньком Atom или Celeron кассы приводила к ощутимому снижению производительности терминала и жалобам на подвисания. Решилось снижением частоты кадров камеры и сменой кодека с MPEG на YUYV 4:2:2.

Был еще забавный момент. Спустя какое-то время после внедрения решения кассиры начали саботировать терминалы. «Да они там глючные, давайте лучше я вас сама посчитаю, быстрее будет». Натурально сговорились и подняли восстание против машин.

Выводы по второй части

Внедрение киосков самообслуживания оказалось успешным. Постепенно люди привыкли и стали постоянно пользоваться ими, даже когда кассиры были свободны.

Однако как масштабировать этот опыт? Одно дело три комплексных обеда, совсем другое, когда блюд в меню 30-40 разных. Очевидно, нужно прокачивать OCR. Прежде чем переходить к заключительной части, попробую порассуждать, почему распознавать еду оказалось так сложно.

Почему распознавать еду сложно?

Во-первых, есть очевидные факторы — освещение, ракурс съемки, шумы и размытия на фото из-за движения подноса в момент захвата изображения, неконтрастный фон и т.д. Во-вторых, есть факторы, непосредственно обусловленные тем, что еда — это, вообще говоря, не цельный объект, а некая нечеткая форма с весьма условными границами.

Когда вы говорите ИИ «распознай кошку», то он ориентируется на датасет кошек. На фотографиях они могут сидеть, лежать, бежать, спать калачиком, но в общем и целом описываются рядом реперных точек, которые подчиняются определенным закономерностям. Нейросеть эти закономерности систематизирует и распознает объект.

С едой все иначе. У нее нет четких границ, практически нет реперных точек (особенно для мелкодисперсной еды, типа каши), текстура часто невыраженная и хаотичная, а цвета далеко не всегда яркие и контрастные.

Борщ сложно отличать не только от свекольника. Очень часто борщ и сам по себе сложно идентифицировать. Где-то положили гуще, где-то жиже. Тут нарезка ингредиентов крупная, а там мелкая. Не говоря уже о ситуациях, когда закончились глубокие суповые тарелки, и суп теперь наливают в глубокие миски для бульона. Ситуация из жизни, если что.

Есть нюансы с отличием схожих блюд с разным ингредиентами.

Вот ризотто с креветками.
Вот ризотто с креветками.
Вот ризотто без креветок.
Вот ризотто без креветок.
А здесь ризотто с омлетом.
А здесь ризотто с омлетом.
Это тоже ризотто. Скорее всего.
Это тоже ризотто. Скорее всего.

К слову, однородную пюрешку распознать проще, чем разноцветное месиво мелко порезанных овощей.

Третий фактор — особенности подачи. Тарелки различаются по форме и цвету, налезают друг на друга, а иногда вместо тарелок — одноразовый контейнер с тем же блюдом. Любой узор на тарелке — дополнительный шум для нейросети и причина расширения тренировочного датасета. Салфетки, вилки, ложки, хлеб на тарелке — тоже.

Наконец, нельзя сбрасывать со счетов и человеческий фактор. Редко, но и такое бывает. Бороться с этим, конечно, бесполезно.

Часть третья: «Обучение через уточнение»

Итак, мы остановились на вопросе масштабирования. Нужно было создать OCR-решение, которое достаточно уверенно распознавало бы десятки блюд, но при этом ошибка распознавания не выливалась бы в какие-то проблемы.

Так родилась концепция обучения через уточнение. Суть в следующем. Предварительно собирается некоторый минимальный датасет для обучения нейросети. Затем терминал устанавливаем в зал, а завершающие фазы обучения проходят непосредственно в процессе заказов клиентами.

Например, если было продано 100 компотов и 3 бифштекса, то прогноз точности распознавания компота будет 100/103 = 97%. А вот для бифштекса лишь около 3%. Уточнений будет намного больше.

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

Результаты: работает, внедряем

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

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


На этом пока все, спасибо, что дочитали. В следующий раз подробнее расскажу про техническую реализацию: выбранные модели, особенности формирования датасетов, какие методы повышения точности распознавания использовали, а также технические моменты внедрения. Подписывайтесь.

Если у вас есть задачи по OCR, требующие экспертного подхода, обращайтесь. Пишите в личку или сюда: https://t.me/delykov

Комментарии (31)


  1. IvanoDigital
    24.11.2025 10:43

    А зачем суп распознавать? Наливай в разные тарелки, а тарелки помечай ...


    1. deniselykov Автор
      24.11.2025 10:43

      Вы правы, это один из возможных способов. Но это дополнительные накладные расходы. Разные тарелки под каждое блюдо - это не бюджетно, больше работы персоналу. Плюс могут перепутать на раздаче. Подход теоретически рабочий, но у нас не прижился.


  1. rybakolbasa
    24.11.2025 10:43

    Надеюсь, бэкенд распознавания не из индусов состоит? :)
    В целом, интересно. Давайте вторую часть.


    1. deniselykov Автор
      24.11.2025 10:43

      Индусы в борщ не умеют)


  1. PoksPoks
    24.11.2025 10:43

    Понравилось, как в итоге покупатель стал частью обучающего пайплайна. Столовская RL-система с человеческим обратным связью, иначе никак


  1. E_BEREZIN
    24.11.2025 10:43

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

    Яйцо вареное и сомнения
    Яйцо вареное и сомнения

    Выбрано "яйцо вареное". Яйцо вареное, молоко сгущеное или ряженка... Разве они похожи, чтобы предлагать выбрать правильный вариант?


    1. deniselykov Автор
      24.11.2025 10:43

      Это, видимо, один из тестовых прогонов, когда систему еще настраивали. Было задано пороговое значение уверенности, и если оно оказывалось ниже, то система выдавала ровно три варианта на выбор. На ранних стадиях обучения правильного варианта среди них могло и не оказаться. Но забавно, да)
      Собственно, эксперименты с разными подходами к обучению все еще продолжаются.


  1. IvanoDigital
    24.11.2025 10:43

    поржать


  1. komogortsev
    24.11.2025 10:43

    а почему бы в расчет брать не только то, что в тарелке, но и то, что в кастрюле осталось? если за последние 5 минут вес кастрюли со свекольником не изменился, а с борщом изменился, то на подносе явно борщ


    1. deniselykov Автор
      24.11.2025 10:43

      Не все так просто.

      1. Очередь. За человеком на кассе стоят еще 50. Вполне возможно, кто-то из них уже взял и борща и свекольника. Мы не сможем в момент расчета точно сопоставить кастрюльный расход с блюдом на кассе.

      2. Человек может попросить налить борща, а потом передумать и оставить на раздаче.

      3. Кастрюли с борщом стоят на подогреве. Весы там в общем случае не предусмотрены.

      Я не утверждаю, что так сделать невозможно, но здесь, как мне кажется, огромное поле для ошибок и человеческого фактора. Намного большее, чем в классическом OCR. ЕМНИП, даже у Amazon полностью автоматический магазин работал как раз за счет индусов, как тут верно отметили.


    1. locoRiply
      24.11.2025 10:43

      систему продавали как "у нас только камера и всё будет работать"

      *когда-то работал прогером на распознавании изображений*


      1. deniselykov Автор
        24.11.2025 10:43

        После обучения - работает. На комплексных обедах - точность 100%. В других форматах ниже, но все еще достаточно высоко, чтобы быть выгодным.


        1. xSVPx
          24.11.2025 10:43

          Один из 2-3 комплексных обедов человек мог выбрать и сам.

          Вообще сломана сама система. Не надо так делать. Надо как у японцев делать. Пока ждешь в очереди в вендинговом автомате покупаешь жетоны на ту еду что тебе нужна(на них прям нарисована конкретная еда, причем они еще и многоразовые часто), потом меняешь их на еду на раздаче. И всё упрощается в разы.

          На сегодня наверняка вместо жетонов можно мобильник использовать...


          1. Squoworode
            24.11.2025 10:43

            Хе-хе... Я на работе несколько раз пытался перед раздачей выбрать по меню, что я хочу сегодня съесть.

            А на раздаче оказывалось - одно кончилось, другого не завезли, третье после 12 часов готовить будут... Зато есть четвёртое и пятое, которых не было в меню.


            1. xSVPx
              24.11.2025 10:43

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

              Уж на сегодня можно вполне адекватно посчитать и обновить что есть, чего нету итд итп. Это вроде бы выглядит куда как проще, чем пробить каждую позицию вручную на кассе.


          1. deniselykov Автор
            24.11.2025 10:43

            Можно как у японцев. А можно как у нас)

            Расскажите подробнее, в чем там суть.


            1. xSVPx
              24.11.2025 10:43

              Читать пробовали ? Выбираешь и оплачиваешь заранее пока ждешь очереди. Кассир не нужен, система распознавания тоже.


              1. deniselykov Автор
                24.11.2025 10:43

                Т.е. терминал все равно есть, только на входе, а не на выходе? И продает он не сами блюда, а жетоны? В некоторых советских столовых была такая схема, только с кассиршей вместо вендингового аппарата и бумажками вместо жетонов. Нифига не быстрее :)

                В общем-то, я не спорю. Можно по всякому. Японцы вообще большие затейники в плане вендинга, как я слышал :)


  1. Yuriy_krd
    24.11.2025 10:43

    Т.е. пользователей заставили выполнять работу кассира ?) А что пользователь получил от этого ? Только что-то мне подсказывает, что внедрение этой системы выйдет дороже, чем ЗП кассира за несколько лет. А эту систему надо еще и обслуживать. Какой смысл в такой системе для владельца? Чем вы обосновывали необходимость внедрения?


    1. deniselykov Автор
      24.11.2025 10:43

      А что пользователь получил от этого ?

      Пользователь получил меньше очередей, удобное и привычное (сегодня) обслуживание. В супермаркетах уже поголовно кассы СО. И туда часто идут, даже когда есть свободные кассиры. Сам пользуюсь каждый день. Здесь по сути то же самое. Вопрос привычки.

      Какой смысл в такой системе для владельца?

      Быстрое обслуживание. Для заводских столовых - это прямое снижение простоев в основной деятельности. У нас был кейс, когда люди элементарно не успевали за обеденный перерыв покушать.

      Кассиры становятся не нужны. Это не только ЗП самих кассиров, но и расходы на их найм, обучение, отпуска, социальные выплаты, а также неизбежные потери на, скажем так, недобросовестность.

      Кстати, найти кассира на низкую зарплату очень сложно, это реальная проблема (плюс еще текучка), а на высокую невыгодно. Обслуживание OCR намного дешевле. Конечно, кассиров можно еще заставить полы мыть и приемку товара делать, но это уже отдельная тема :)


  1. Graf_sheremetev
    24.11.2025 10:43

    А вся эта система работает оффлайн?


    1. deniselykov Автор
      24.11.2025 10:43

      Оплата на терминале работает. Обучать новым блюдам тоже можно оффлайн. Для апдейтов самой нейросети нужен интернет.

      Однако на самом деле это неважно, потому что кассы ныне обязаны работать через Честный знак и ОФД. А они только онлайн. Увы.


      1. sSindiKk
        24.11.2025 10:43

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

        Не совсем понял, что вы имеете ввиду под "Обучать новым блюдам тоже можно оффлайн." Терминал сможет сам дообучиться? Разве для этого не нужен будет отдельный сервер?


  1. iioblomov
    24.11.2025 10:43

    Одно источника информации о предмете (OCR) здесь явно не достаточно. У мозга живого организма их явно больше при этом он (мозг) не всегда может сделать правильные выводы.
    Нужен "электронный нос" - https://habr.com/ru/companies/first/articles/695986/ :-)


  1. digrobot
    24.11.2025 10:43

    OCR - это Optical Character Recognition, распознавание текста. А здесь Object Detection.
    При достаточно точной модели все должно работать мгновенно, в сравнении с кассиром . Поднос неподвижен, достаточно одного кадра, освещение можно поставить - идеальные условия.


    1. xSVPx
      24.11.2025 10:43

      Ну вам же даже в статье показали фото котлет и ризотто. Тут и человек фиг определит, не то что нейросеть. Внешний вид еды неспецифицирован и разные повара будут разную картинку генерировать, по одному рецепту заметьте. Добавить к этому разные емкости и разные подносы и получается не такая уж простая задача. Без дообучения тут никак.

      Интересно быстро ли граждане начнут обучать что это не бутерброды с икрой, а стакан кефира ...


      1. digrobot
        24.11.2025 10:43

        Ну показали, и что я, котлеты от компота не отличу? И креветки в рисе видно.
        Человек-кассир определяет, значит, и нейросеть может. Просто в датасете нужны разные виды котлет, а не с одной столовой.


        1. deniselykov Автор
          24.11.2025 10:43

          Так и есть. Человек видит сразу (хотя тоже не всегда), а нейросеть нужно обучать. А в датасет нужно включать разные виды котлет от разных поваров. Обо всем этом как раз и идет речь в статье. Технические моменты - в следующих.


    1. deniselykov Автор
      24.11.2025 10:43

      Поднос неподвижен, достаточно одного кадра

      Если бы :)


  1. konar24
    24.11.2025 10:43

    Эксплуатирование труда покупателей ради экономии на кассирах интересная затея, но тут так же много слабых мест, например, в магазине, если не пробил товар на кассе, то он запищит на выходе, здесь же мы имеем блюдо без упаковки и естественный в рост недобросовестных посетителей.
    Так же возможно пробитие более дешевого товара в случае, когда его необходимо уточнить, думаю это актуально для напитков таких как вариации кофе или каркаде/компот.
    Есть какой-то контроль от хитрецов?


    1. deniselykov Автор
      24.11.2025 10:43

      Такая проблема существует, но ее масштабы не такие большие как может показаться. Кроме того, в корпоративных или заводских столовых оплата часто идет картой сотрудника, а не банковской, поэтому выявить системных нарушителей не так уж и сложно. Все ж в личном кабинете отражается.