HoloLens (1-го поколения) и Azure 303: распознавание естественной речи (LUIS)


Примечание

Руководства Mixed Reality Academy были разработаны для иммерсивных гарнитур HoloLens (1-го поколения) и иммерсивных гарнитур Mixed Reality. Поэтому мы считаем, что важно оставить эти руководства для разработчиков, которые ищут рекомендации по разработке для этих устройств. Данные руководства не будут обновляться с учетом последних наборов инструментов или возможностей взаимодействия для HoloLens 2. Они будут сохранены для работы на поддерживаемых устройствах. В будущем будет опубликована новая серия учебников, демонстрирующих разработку для HoloLens 2. В этом уведомлении будет добавлена ссылка на эти руководства при их публикации.


В этом курсе вы узнаете, как интегрировать Распознавание речи в приложение смешанной реальности с помощью Azure Cognitive Services с api Распознавание речи.

Результат лаборатории

Распознавание речи (LUIS) — это служба Microsoft Azure, которая предоставляет приложениям возможность делать смысл из пользовательского ввода, например путем извлечения того, что человек может захотеть, своими словами. Это достигается с помощью машинного обучения, которое понимает и изучает входную информацию, а затем может отвечать с подробными, актуальными сведениями. Дополнительные сведения см. на странице Azure Распознавание речи (LUIS).

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

  1. Запишите ввод речи пользователя с помощью микрофона, подключенного к иммерсивной гарнитуре.
  2. Отправьте записанную диктовку azure Распознавание речи Intelligent Service (LUIS).
  3. Попросите LUIS извлечь значение из отправляемой информации, которая будет проанализирована, и попытаться определить намерение запроса пользователя.

Разработка будет включать создание приложения, в котором пользователь сможет использовать голос и (или) взгляд для изменения размера и цвета объектов в сцене. Использование контроллеров движения не будет охвачено.

В приложении вы определяете, как вы будете интегрировать результаты в проект. Этот курс предназначен для обучения интеграции службы Azure с проектом Unity. Ваша задача — использовать знания, полученные из этого курса, для улучшения приложения смешанной реальности.

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

Поддержка устройств

Курс HoloLens Иммерсивные гарнитуры
Mr и Azure 303: распознавание естественной речи (LUIS) ✔️ ✔️

Примечание

Хотя в этом курсе основное внимание уделяется Windows Mixed Reality иммерсивным гарнитурам ( VR), вы также можете применить то, что вы узнали в этом курсе, для Microsoft HoloLens. По мере прохождения курса вы увидите заметки о любых изменениях, которые могут потребоваться для поддержки HoloLens. При использовании HoloLens вы можете заметить некоторое эхо во время захвата голоса.

Предварительные требования

Примечание

Это руководство предназначено для разработчиков, имеющих базовый опыт работы с Unity и C#. Кроме того, имейте в виду, что предварительные требования и письменные инструкции в этом документе представляют то, что было протестировано и проверено на момент написания статьи (май 2018 г.). Вы можете использовать последнюю версию программного обеспечения, как указано в статье установка инструментов , хотя не следует предполагать, что информация в этом курсе будет полностью соответствовать тому, что вы найдете в более новом программном обеспечении, чем указано ниже.

Для этого курса мы рекомендуем использовать следующее оборудование и программное обеспечение:

Перед началом работы

  1. Чтобы избежать проблем со сборкой этого проекта, настоятельно рекомендуется создать проект, упомянутый в этом руководстве, в корневой или почти корневой папке (длинные пути к папкам могут вызвать проблемы во время сборки).

  2. Чтобы разрешить компьютеру включить диктовку, перейдите в раздел Параметры > Windows Конфиденциальность > Речь, Рукописный ввод & Ввод и нажмите кнопку Включить службы распознавания речи и предложения ввода.

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

  4. Если гарнитура имеет встроенный микрофон, убедитесь, что в параметрах портала Смешанная реальность включен параметр "Когда я ношу гарнитуру, переключаться на микрофон гарнитуры".

    Настройка иммерсивной гарнитуры

Глава 1. Настройка портала Azure

Чтобы использовать службу Распознавание речи в Azure, необходимо настроить экземпляр службы, чтобы сделать его доступным для приложения.

  1. Войдите на портал Azure.

    Примечание

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

  2. После входа щелкните Создать в левом верхнем углу, найдите Распознавание речи и нажмите клавишу ВВОД.

    Создание ресурсов LUIS

    Примечание

    На более новых порталах слово "Создать " может быть заменено на "Создать ресурс".

  3. На новой странице справа будет представлено описание службы Распознавание речи. В левом нижнем углу этой страницы нажмите кнопку Создать , чтобы создать экземпляр этой службы.

    Создание службы LUIS — юридическое уведомление

  4. После нажатия кнопки Создать:

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

    2. Выберите подписку.

    3. Выберите подходящую ценовую категорию . Если вы создаете службу LUIS впервые, вам должен быть доступен бесплатный уровень (F0). Свободного распределения должно быть более чем достаточно для этого курса.

    4. Выберите группу ресурсов или создайте новую. Группа ресурсов предоставляет способ мониторинга, контроля доступа, подготовки и управления выставлением счетов для коллекции ресурсов Azure. Рекомендуется сохранить все службы Azure, связанные с одним проектом (например, эти курсы), в общей группе ресурсов.

      Дополнительные сведения о группах ресурсов Azure см. в этой статье.

    5. Определите расположение для группы ресурсов (если вы создаете новую группу ресурсов). Расположение в идеале должно находиться в регионе, где будет выполняться приложение. Некоторые ресурсы Azure доступны только в определенных регионах.

    6. Вам также потребуется подтвердить, что вы понимаете условия, применяемые к этой Службе.

    7. Нажмите кнопку создания.

      Создание службы LUIS — ввод данных пользователем

  5. После нажатия кнопки Создать вам придется подождать, пока служба будет создана. Это может занять минуту.

  6. После создания экземпляра службы на портале появится уведомление.

    Новый образ уведомления Azure

  7. Щелкните уведомление, чтобы просмотреть новый экземпляр службы.

    Уведомление об успешном создании ресурса

  8. Нажмите кнопку Перейти к ресурсу в уведомлении, чтобы просмотреть новый экземпляр службы. Вы перейдете к новому экземпляру службы LUIS.

    Доступ к ключам LUIS

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

  10. На странице Быстрого запуска службы API LUIS перейдите к первому шагу Захват ключей и щелкните Ключи (это также можно сделать, щелкнув синюю гиперссылку Ключи, расположенную в меню навигации служб и обозначенную значком ключа). Вы увидите ключи службы.

  11. Создайте копию одного из отображаемых ключей, так как она понадобится вам позже в проекте.

  12. На странице Служба щелкните портал Распознавание речи, чтобы перенаправить его на веб-страницу, которая будет использоваться для создания службы в приложении LUIS.

Глава 2. Портал Распознавание речи

В этом разделе вы узнаете, как создать приложение LUIS на портале LUIS.

Важно!

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

  1. После входа на портал Распознавание речи, возможно, потребуется войти с теми же учетными данными, что и портал Azure.

    Страница входа LUIS

  2. Если вы впервые используете LUIS, прокрутите страницу приветствия вниз, чтобы найти и нажать кнопку Создать приложение LUIS .

    Страница создания приложения LUIS

  3. После входа в систему щелкните Мои приложения (если вы не находитесь в этом разделе в настоящее время). Затем можно щелкнуть Создать приложение.

    LUIS — изображение

  4. Укажите имя приложения.

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

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

    LUIS — создание приложения

  7. После нажатия кнопки Готово вы перейдете на страницу Сборка нового приложения LUIS .

  8. Ниже приведены некоторые важные понятия.

    • Намерение представляет метод, который будет вызываться после запроса от пользователя. Намерение может иметь одну или несколько СУЩНОСТЕЙ.
    • Сущность — это компонент запроса, описывающий сведения, относящиеся к намерению.
    • Речевые фрагменты — это примеры запросов, предоставленных разработчиком, которые LUIS будет использовать для обучения.

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

Вы начнете с создания сущностей, необходимых для создания этого курса.

  1. В левой части страницы щелкните Сущности, а затем — Создать сущность.

    Создание сущности

  2. Вызовите новый цвет сущности, задайте для нее тип Простой, а затем нажмите кнопку Готово.

    Создание простой сущности — color

  3. Повторите эту процедуру, чтобы создать еще три (3) простых сущности с именами:

    • upsize
    • Сократить
    • target

Результат должен выглядеть следующим образом:

Результат создания сущности

На этом этапе можно приступить к созданию намерений.

Предупреждение

Не удаляйте намерение None .

  1. В левой части страницы щелкните Намерения, а затем — Создать новое намерение.

    Создание новых намерений

  2. Вызовите новое намерениеChangeObjectColor.

    Важно!

    Это имя намерения используется в коде далее в этом курсе, поэтому для достижения наилучших результатов используйте это имя точно так, как указано.

После подтверждения имени вы будете перенаправлены на страницу намерений.

LUIS — страница намерений

Вы заметите, что есть текстовое поле с запросом на ввод 5 или более различных речевых фрагментов.

Примечание

LUIS преобразует все речевые фрагменты в нижний регистр.

  1. Вставьте следующий фрагмент в текстовое поле (в настоящее время с текстом Введите около 5 примеров... ) и нажмите клавишу ВВОД:
The color of the cylinder must be red

Вы заметите, что новый речевый фрагмент появится в списке под ним.

После того же процесса вставьте следующие шесть (6) речевых фрагментов:

make the cube black

make the cylinder color white

change the sphere to red

change it to green

make this yellow

change the color of this object to blue

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

  1. Для этого попробуйте щелкнуть слово цилиндр в первом высказывании и выбрать целевой объект.

    Определение целевых объектов речевых фрагментов

  2. Теперь щелкните слово red в первом речевом фрагменте и выберите цвет.

    Определение сущностей речевого фрагмента

  3. Также пометка следующей строки, где куб должен быть целевым, а черныйцветом. Обратите внимание также на использование слов "this", "it" и "this object", которые мы предоставляем, чтобы также иметь неспецифические целевые типы.

  4. Повторяйте описанную выше процедуру, пока все речевые фрагменты не будут помечены как Сущности. Если вам нужна помощь, см. приведенный ниже рисунок.

    Совет

    Выбрав слова, которые следует пометить, как сущности, сделайте следующее:

    • Для отдельных слов просто щелкните их.
    • Для набора из двух или более слов щелкните в начале, а затем в конце набора.

    Примечание

    Вы можете использовать переключатель Представление маркеров для переключения между сущностями и представлением токенов!

  5. Результаты должны выглядеть так, как показано на рисунках ниже, в представлении Сущности и токены:

    Представления маркеров & сущностей

  6. На этом этапе нажмите кнопку Train (Обучить ) в правом верхнем углу страницы и дождитесь, пока маленький круглый индикатор на нем не зазелеет. Это означает, что СЛУЖБА LUIS успешно обучена распознавать это намерение.

    Обучение LUIS

  7. В качестве упражнения создайте намерение с именем ChangeObjectSize с помощью целевого объекта Entities, upsize и downsize.

  8. Выполнив ту же процедуру, что и предыдущее намерение, вставьте следующие восемь (8) речевых фрагментов для изменения размера :

    increase the dimensions of that
    
    reduce the size of this
    
    i want the sphere smaller
    
    make the cylinder bigger
    
    size down the sphere
    
    size up the cube
    
    decrease the size of that object
    
    increase the size of this object
    
  9. Результат должен быть таким же, как на рисунке ниже:

    Настройка токенов и сущностей ChangeObjectSize

  10. После создания и обучения намерений ( ChangeObjectColor и ChangeObjectSize) нажмите кнопку ОПУБЛИКОВАТЬ в верхней части страницы.

    Публикация службы LUIS

  11. На странице Публикация вы завершите работу и опубликуете приложение LUIS, чтобы получить к нему доступ с помощью кода.

    1. Задайте для раскрывающегося списка Опубликовать в качестве рабочей.

    2. Задайте для часового пояса свой часовой пояс.

    3. Установите флажок Включить все прогнозируемые оценки намерений.

    4. Щелкните Опубликовать в рабочем слоте.

      Параметры публикации

  12. В разделе Ресурсы и ключи:

    1. Выберите регион, заданный для экземпляра службы, на портале Azure.
    2. Вы заметите Starter_Key элемент ниже, проигнорируйте его.
    3. Щелкните Добавить ключ и вставьте ключ , полученный на портале Azure при создании экземпляра службы. Если ваш портал Azure и LUIS вошли в один и тот же пользователь, вам будут предоставлены раскрывающееся меню имя клиента, имя подписки и ключ , который вы хотите использовать (будут иметь то же имя, что и на портале Azure).

    Важно!

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

Глава 3. Настройка проекта Unity

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

  1. Откройте Unity и нажмите кнопку Создать.

    Запустите новый проект Unity.

  2. Теперь необходимо указать имя проекта Unity, вставить MR_LUIS. Убедитесь, что для типа проекта задано значение 3D. Задайте для параметра Расположение подходящее место (помните, что лучше ближе к корневым каталогам). Затем щелкните Создать проект.

    Укажите сведения о новом проекте Unity.

  3. При открытии Unity стоит проверить, что для редактора скриптов по умолчанию задано значение Visual Studio. Перейдите в раздел Изменение > параметров, а затем в новом окне перейдите к разделу Внешние инструменты. Измените внешний редактор скриптов на Visual Studio 2017. Закройте окно Параметры .

    Обновление настроек редактора скриптов.

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

    Окно параметров сборки, переключение платформы на UWP.

  5. Перейдите в раздел Параметры сборки файлов > и убедитесь, что:

    1. Для целевого устройства задано значение Любое устройство.

      Для Microsoft HoloLens задайте для параметра Целевое устройство значение HoloLens.

    2. Для параметра Тип сборки задано значение D3D.

    3. Для пакета SDK задано значение Последняя установленная версия.

    4. Версия Visual Studio имеет значение Последняя установленная

    5. Для сборки и запуска задано значение Локальный компьютер.

    6. Сохраните сцену и добавьте ее в сборку.

      1. Для этого выберите Добавить открытые сцены. Откроется окно сохранения.

        Нажмите кнопку

      2. Создайте новую папку для этой и любой будущей сцены, а затем нажмите кнопку Создать папку , чтобы создать новую папку и назовите ее Сцены.

        Создание папки скриптов

      3. Откройте только что созданную папку Scenes , а затем в текстовом поле Имя файла введите MR_LuisScene, а затем нажмите кнопку Сохранить.

        Присвойте новой сцене имя.

    7. Остальные параметры в разделе Параметры сборки пока следует оставить по умолчанию.

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

    Откройте параметры проигрывателя.

  7. На этой панели необходимо проверить несколько параметров:

    1. На вкладке Другие параметры :

      1. Версия среды выполнения скриптов должна быть стабильной (эквивалент .NET 3.5).

      2. Серверная часть сценариев должна быть .NET

      3. Уровень совместимости API должен быть .NET 4.6

        Обновите другие параметры.

    2. На вкладке Параметры публикации в разделе Возможности проверка:

      1. InternetClient;

      2. Микрофон

        Обновление параметров публикации.

    3. Далее вниз по панели в разделе Параметры XR (см. раздел Параметры публикации) установите флажок Виртуальная реальность Поддерживается, убедитесь, что пакет SDK для Windows Mixed Reality добавлен.

      Обновите параметры X R.

  8. Вернувшись в параметры сборки, проекты Unity C# больше не выделены серым цветом; Установите флажок рядом с этим.

  9. Закройте окно Build Settings (Параметры сборки).

  10. Сохраните сцену и проект (ФАЙЛ > СОХРАНИТЬ СЦЕНУ или ФАЙЛ > СОХРАНИТЬ ПРОЕКТ).

Глава 4. Создание сцены

Важно!

Если вы хотите пропустить компонент Unity Set up этого курса и перейти непосредственно к коду, скачайте этот пакет unitypackage, импортируйте его в проект в виде пользовательского пакета, а затем перейдите к главе 5.

  1. Щелкните правой кнопкой мыши пустую область панели иерархии, в разделе Трехмерный объект добавьте плоскость.

    Создайте плоскость.

  2. Имейте в виду, что при повторном щелчке правой кнопкой мыши в иерархии для создания дополнительных объектов, если выбран последний объект, выбранный объект будет родительским для нового объекта. Избегайте щелчка левой кнопкой мыши в пустом пространстве в иерархии, а затем щелчка правой кнопкой мыши.

  3. Повторите описанную выше процедуру, чтобы добавить следующие объекты:

    1. Sphere
    2. Цилиндр
    3. Cube
    4. Трехмерный текст
  4. Результирующая иерархия сцены должна быть такой же, как на рисунке ниже:

    Настройка иерархии сцен.

  5. Щелкните левой кнопкой мыши основную камеру , чтобы выбрать ее. На панели инспектора вы увидите объект Камера со всеми его компонентами.

  6. Нажмите кнопку Добавить компонент в нижней части панели инспектора.

    Добавление источника звука

  7. Найдите компонент с именем Источник звука, как показано выше.

  8. Кроме того, убедитесь, что для компонента Преобразование основной камеры задано значение (0,0,0). Это можно сделать, нажав значок Шестеренки рядом с компонентом Преобразование камеры и выбрав Сбросить. Затем компонент Transform должен выглядеть следующим образом:

    1. Позиция имеет значение 0, 0, 0.
    2. Для поворота задано значение 0, 0, 0.

    Примечание

    Для Microsoft HoloLens необходимо также изменить следующие компоненты, которые являются частью компонента "Камера", который находится на главной камере:

    • Очистить флаги: Сплошной цвет.
    • Фон "Черный, альфа 0" — шестнадцатеричный цвет: #0000000.
  9. Щелкните левой кнопкой мыши плоскость, чтобы выбрать его. На панели инспектора задайте для компонента Transform следующие значения:

    Ось X Ось Y Ось Z
    0 -1 0
  10. Щелкните поле Sphere левой кнопкой мыши, чтобы выбрать его. На панели инспектора задайте для компонента Transform следующие значения:

    Ось X Ось Y Ось Z
    2 1 2
  11. Щелкните цилиндр левой кнопкой мыши, чтобы выбрать его. На панели инспектора задайте для компонента Transform следующие значения:

    Ось X Ось Y Ось Z
    -2 1 2
  12. Щелкните куб левой кнопкой мыши, чтобы выбрать его. На панели инспектора задайте для компонента Transform следующие значения:

Преобразование — положение

X да Z
0 1 4

Преобразование — поворот

X да Z
45 45 0
  1. Щелкните левой кнопкой мыши объект Создать текст , чтобы выделить его. На панели инспектора задайте для компонента Transform следующие значения:

Преобразование — положение

X да Z
-2 6 9

Преобразование — масштабирование

X да Z
0,1 0,1 0,1
  1. Измените размер шрифта в компоненте Сетка текста на 50.

  2. Измените имя объекта Сетка текста на Текст диктовки.

    Создание объекта трехмерного текста

  3. Теперь структура панели иерархии должна выглядеть следующим образом:

    сетка текста в представлении сцены

  4. Последняя сцена должна выглядеть следующим образом:

    Представление сцены.

Глава 5. Создание класса MicrophoneManager

Первый скрипт, который вы собираетесь создать, — это класс MicrophoneManager . После этого вы создадите LuisManager, класс Behaviours и, наконец, класс Gaze (вы можете создать все это сейчас, хотя они будут рассмотрены по мере достижения каждой главы).

Класс MicrophoneManager отвечает за:

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

Чтобы создать этот класс, выполните указанные ниже действия.

  1. Щелкните правой кнопкой мыши на панели проект, создайте > папку. Вызовите папку Scripts.

    Создайте папку Scripts.

  2. Создав папку Scripts , дважды щелкните ее, чтобы открыть. Затем в этой папке щелкните правой кнопкой мыши команду Создать > скрипт C#. Присвойте скрипту имя MicrophoneManager.

  3. Дважды щелкните MicrophoneManager , чтобы открыть его в Visual Studio.

  4. Добавьте следующие пространства имен в начало файла:

        using UnityEngine;
        using UnityEngine.Windows.Speech;
    
  5. Затем добавьте следующие переменные в класс MicrophoneManager :

        public static MicrophoneManager instance; //help to access instance of this object
        private DictationRecognizer dictationRecognizer;  //Component converting speech to text
        public TextMesh dictationText; //a UI object used to debug dictation result
    
  6. Теперь необходимо добавить код для методов Awake() и Start( ). Они будут вызываться при инициализации класса:

        private void Awake()
        {
            // allows this class instance to behave like a singleton
            instance = this;
        }
    
        void Start()
        {
            if (Microphone.devices.Length > 0)
            {
                StartCapturingAudio();
                Debug.Log("Mic Detected");
            }
        }
    
  7. Теперь вам нужен метод, который приложение использует для запуска и остановки голосового захвата и передачи его в класс LuisManager , который вы создадите в ближайшее время.

        /// <summary>
        /// Start microphone capture, by providing the microphone as a continual audio source (looping),
        /// then initialise the DictationRecognizer, which will capture spoken words
        /// </summary>
        public void StartCapturingAudio()
        {
            if (dictationRecognizer == null)
            {
                dictationRecognizer = new DictationRecognizer
                {
                    InitialSilenceTimeoutSeconds = 60,
                    AutoSilenceTimeoutSeconds = 5
                };
    
                dictationRecognizer.DictationResult += DictationRecognizer_DictationResult;
                dictationRecognizer.DictationError += DictationRecognizer_DictationError;
            }
            dictationRecognizer.Start();
            Debug.Log("Capturing Audio...");
        }
    
        /// <summary>
        /// Stop microphone capture
        /// </summary>
        public void StopCapturingAudio()
        {
            dictationRecognizer.Stop();
            Debug.Log("Stop Capturing Audio...");
        }
    
  8. Добавьте обработчик диктовки , который будет вызываться при приостановке голоса. Этот метод передает текст диктовки в класс LuisManager .

        /// <summary>
        /// This handler is called every time the Dictation detects a pause in the speech. 
        /// This method will stop listening for audio, send a request to the LUIS service 
        /// and then start listening again.
        /// </summary>
        private void DictationRecognizer_DictationResult(string dictationCaptured, ConfidenceLevel confidence)
        {
            StopCapturingAudio();
            StartCoroutine(LuisManager.instance.SubmitRequestToLuis(dictationCaptured, StartCapturingAudio));
            Debug.Log("Dictation: " + dictationCaptured);
            dictationText.text = dictationCaptured;
        }
    
        private void DictationRecognizer_DictationError(string error, int hresult)
        {
            Debug.Log("Dictation exception: " + error);
        }
    

    Важно!

    Удалите метод Update(), так как этот класс не будет использовать его.

  9. Перед возвращением в Unity обязательно сохраните изменения в Visual Studio.

    Примечание

    На этом этапе вы заметите ошибку на панели консоли редактора Unity. Это связано с тем, что код ссылается на класс LuisManager , который будет создан в следующей главе.

Глава 6. Создание класса LUISManager

Пора создать класс LuisManager , который будет выполнять вызов службы Azure LUIS.

Цель этого класса — получить текст диктовки из класса MicrophoneManager и отправить его в API Распознавание речи Azure для анализа.

Этот класс десериализует ответ JSON и вызовет соответствующие методы класса Behaviours для активации действия.

Чтобы создать этот класс, выполните указанные ниже действия.

  1. Дважды щелкните папку Скрипты , чтобы открыть ее.

  2. Щелкните правой кнопкой мыши в папке Скрипты и выберите Создать > скрипт C#. Назовите скрипт LuisManager.

  3. Дважды щелкните скрипт, чтобы открыть его с помощью Visual Studio.

  4. Добавьте следующие пространства имен в начало файла:

        using System;
        using System.Collections;
        using System.Collections.Generic;
        using System.IO;
        using UnityEngine;
        using UnityEngine.Networking;
    
  5. Для начала вы создадите три класса в классе LuisManager (в том же файле скрипта, над методом Start(), которые будут представлять десериализованный ответ JSON из Azure.

        [Serializable] //this class represents the LUIS response
        public class AnalysedQuery
        {
            public TopScoringIntentData topScoringIntent;
            public EntityData[] entities;
            public string query;
        }
    
        // This class contains the Intent LUIS determines 
        // to be the most likely
        [Serializable]
        public class TopScoringIntentData
        {
            public string intent;
            public float score;
        }
    
        // This class contains data for an Entity
        [Serializable]
        public class EntityData
        {
            public string entity;
            public string type;
            public int startIndex;
            public int endIndex;
            public float score;
        }
    
  6. Затем добавьте следующие переменные в класс LuisManager :

        public static LuisManager instance;
    
        //Substitute the value of luis Endpoint with your own End Point
        string luisEndpoint = "https://westus.api.cognitive... add your endpoint from the Luis Portal";
    
  7. Обязательно поместите конечную точку LUIS сейчас (которую вы будете использовать на портале LUIS).

  8. Теперь необходимо добавить код для метода Awake( ). Этот метод будет вызываться при инициализации класса:

        private void Awake()
        {
            // allows this class instance to behave like a singleton
            instance = this;
        }
    
  9. Теперь вам потребуются методы, которые приложение использует для отправки диктовки, полученной от класса MicrophoneManager , в LUIS, а затем получения и десериализации ответа.

  10. После определения значения Intent и связанных сущностей они передаются экземпляру класса Behaviours для активации предполагаемого действия.

        /// <summary>
        /// Call LUIS to submit a dictation result.
        /// The done Action is called at the completion of the method.
        /// </summary>
        public IEnumerator SubmitRequestToLuis(string dictationResult, Action done)
        {
            string queryString = string.Concat(Uri.EscapeDataString(dictationResult));
    
            using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(luisEndpoint + queryString))
            {
                yield return unityWebRequest.SendWebRequest();
    
                if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
                {
                    Debug.Log(unityWebRequest.error);
                }
                else
                {
                    try
                    {
                        AnalysedQuery analysedQuery = JsonUtility.FromJson<AnalysedQuery>(unityWebRequest.downloadHandler.text);
    
                        //analyse the elements of the response 
                        AnalyseResponseElements(analysedQuery);
                    }
                    catch (Exception exception)
                    {
                        Debug.Log("Luis Request Exception Message: " + exception.Message);
                    }
                }
    
                done();
                yield return null;
            }
        }
    
  11. Создайте метод с именем AnalyseResponseElements(), который будет считывать результирующий объект AnalysedQuery и определять сущности. После определения этих сущностей они будут переданы экземпляру класса Поведения для использования в действиях.

        private void AnalyseResponseElements(AnalysedQuery aQuery)
        {
            string topIntent = aQuery.topScoringIntent.intent;
    
            // Create a dictionary of entities associated with their type
            Dictionary<string, string> entityDic = new Dictionary<string, string>();
    
            foreach (EntityData ed in aQuery.entities)
            {
                entityDic.Add(ed.type, ed.entity);
            }
    
            // Depending on the topmost recognized intent, read the entities name
            switch (aQuery.topScoringIntent.intent)
            {
                case "ChangeObjectColor":
                    string targetForColor = null;
                    string color = null;
    
                    foreach (var pair in entityDic)
                    {
                        if (pair.Key == "target")
                        {
                            targetForColor = pair.Value;
                        }
                        else if (pair.Key == "color")
                        {
                            color = pair.Value;
                        }
                    }
    
                    Behaviours.instance.ChangeTargetColor(targetForColor, color);
                    break;
    
                case "ChangeObjectSize":
                    string targetForSize = null;
                    foreach (var pair in entityDic)
                    {
                        if (pair.Key == "target")
                        {
                            targetForSize = pair.Value;
                        }
                    }
    
                    if (entityDic.ContainsKey("upsize") == true)
                    {
                        Behaviours.instance.UpSizeTarget(targetForSize);
                    }
                    else if (entityDic.ContainsKey("downsize") == true)
                    {
                        Behaviours.instance.DownSizeTarget(targetForSize);
                    }
                    break;
            }
        }
    

    Важно!

    Удалите методы Start() и Update(), так как этот класс не будет использовать их.

  12. Перед возвращением в Unity обязательно сохраните изменения в Visual Studio.

Примечание

На этом этапе вы заметите несколько ошибок на панели консоли редактора Unity. Это связано с тем, что код ссылается на класс Behaviours , который вы создадите в следующей главе.

Глава 7. Создание класса Поведения

Класс Behaviours активирует действия с помощью сущностей, предоставляемых классом LuisManager .

Чтобы создать этот класс, выполните указанные ниже действия.

  1. Дважды щелкните папку Скрипты , чтобы открыть ее.

  2. Щелкните правой кнопкой мыши в папке Скрипты и выберите Создать > скрипт C#. Присвойте скрипту имя Поведения.

  3. Дважды щелкните скрипт, чтобы открыть его с помощью Visual Studio.

  4. Затем добавьте следующие переменные в класс Behaviours :

        public static Behaviours instance;
    
        // the following variables are references to possible targets
        public GameObject sphere;
        public GameObject cylinder;
        public GameObject cube;
        internal GameObject gazedTarget;
    
  5. Добавьте код метода Awake(). Этот метод будет вызываться при инициализации класса:

        void Awake()
        {
            // allows this class instance to behave like a singleton
            instance = this;
        }
    
  6. Следующие методы вызываются классом LuisManager (который вы создали ранее), чтобы определить, какой объект является целевым объектом запроса, а затем активировать соответствующее действие.

        /// <summary>
        /// Changes the color of the target GameObject by providing the name of the object
        /// and the name of the color
        /// </summary>
        public void ChangeTargetColor(string targetName, string colorName)
        {
            GameObject foundTarget = FindTarget(targetName);
            if (foundTarget != null)
            {
                Debug.Log("Changing color " + colorName + " to target: " + foundTarget.name);
    
                switch (colorName)
                {
                    case "blue":
                        foundTarget.GetComponent<Renderer>().material.color = Color.blue;
                        break;
    
                    case "red":
                        foundTarget.GetComponent<Renderer>().material.color = Color.red;
                        break;
    
                    case "yellow":
                        foundTarget.GetComponent<Renderer>().material.color = Color.yellow;
                        break;
    
                    case "green":
                        foundTarget.GetComponent<Renderer>().material.color = Color.green;
                        break;
    
                    case "white":
                        foundTarget.GetComponent<Renderer>().material.color = Color.white;
                        break;
    
                    case "black":
                        foundTarget.GetComponent<Renderer>().material.color = Color.black;
                        break;
                }          
            }
        }
    
        /// <summary>
        /// Reduces the size of the target GameObject by providing its name
        /// </summary>
        public void DownSizeTarget(string targetName)
        {
            GameObject foundTarget = FindTarget(targetName);
            foundTarget.transform.localScale -= new Vector3(0.5F, 0.5F, 0.5F);
        }
    
        /// <summary>
        /// Increases the size of the target GameObject by providing its name
        /// </summary>
        public void UpSizeTarget(string targetName)
        {
            GameObject foundTarget = FindTarget(targetName);
            foundTarget.transform.localScale += new Vector3(0.5F, 0.5F, 0.5F);
        }
    
  7. Добавьте метод FindTarget(), чтобы определить, какой из объектов GameObject является целевым объектом текущего намерения. Этот метод по умолчанию использует целевой объект GameObject , если в сущностях не определен явный целевой объект.

        /// <summary>
        /// Determines which object reference is the target GameObject by providing its name
        /// </summary>
        private GameObject FindTarget(string name)
        {
            GameObject targetAsGO = null;
    
            switch (name)
            {
                case "sphere":
                    targetAsGO = sphere;
                    break;
    
                case "cylinder":
                    targetAsGO = cylinder;
                    break;
    
                case "cube":
                    targetAsGO = cube;
                    break;
    
                case "this": // as an example of target words that the user may use when looking at an object
                case "it":  // as this is the default, these are not actually needed in this example
                case "that":
                default: // if the target name is none of those above, check if the user is looking at something
                    if (gazedTarget != null) 
                    {
                        targetAsGO = gazedTarget;
                    }
                    break;
            }
            return targetAsGO;
        }
    

    Важно!

    Удалите методы Start() и Update(), так как этот класс не будет использовать их.

  8. Перед возвращением в Unity обязательно сохраните изменения в Visual Studio.

Глава 8. Создание класса Gaze

Последним классом, который вам потребуется для завершения этого приложения, является класс Gaze . Этот класс обновляет ссылку на GameObject в настоящее время в визуальном фокусе пользователя.

Чтобы создать этот класс, выполните указанные ниже действия.

  1. Дважды щелкните папку Скрипты , чтобы открыть ее.

  2. Щелкните правой кнопкой мыши в папке Скрипты и выберите Создать > скрипт C#. Присвойте скрипту имя Gaze.

  3. Дважды щелкните скрипт, чтобы открыть его в Visual Studio.

  4. Вставьте следующий код для этого класса:

        using UnityEngine;
    
        public class Gaze : MonoBehaviour
        {        
            internal GameObject gazedObject;
            public float gazeMaxDistance = 300;
    
            void Update()
            {
                // Uses a raycast from the Main Camera to determine which object is gazed upon.
                Vector3 fwd = gameObject.transform.TransformDirection(Vector3.forward);
                Ray ray = new Ray(Camera.main.transform.position, fwd);
                RaycastHit hit;
                Debug.DrawRay(Camera.main.transform.position, fwd);
    
                if (Physics.Raycast(ray, out hit, gazeMaxDistance) && hit.collider != null)
                {
                    if (gazedObject == null)
                    {
                        gazedObject = hit.transform.gameObject;
    
                        // Set the gazedTarget in the Behaviours class
                        Behaviours.instance.gazedTarget = gazedObject;
                    }
                }
                else
                {
                    ResetGaze();
                }         
            }
    
            // Turn the gaze off, reset the gazeObject in the Behaviours class.
            public void ResetGaze()
            {
                if (gazedObject != null)
                {
                    Behaviours.instance.gazedTarget = null;
                    gazedObject = null;
                }
            }
        }
    
  5. Перед возвращением в Unity обязательно сохраните изменения в Visual Studio.

Глава 9. Завершение настройки сцены

  1. Чтобы завершить настройку сцены, перетащите каждый созданный скрипт из папки Scripts в объект Main Camera на панели иерархии.

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

    Задание эталонных целевых объектов камеры.

  3. Чтобы правильно задать эти параметры, выполните следующие инструкции:

    1. MicrophoneManager:

      • С панели иерархии перетащите объект Dictation Text (Текст диктовки ) в поле значение параметра Dictation Text (Текст диктовки ).
    2. Поведение на панели иерархии:

      • Перетащите объект Sphere в поле Целевой объект ссылки Sphere .
      • Перетащите цилиндр в поле Целевой объект цилиндра .
      • Перетащите куб в поле Целевой объект ссылки на куб .
    3. Взгляд:

      • Задайте для параметра Максимальное расстояние взгляда значение 300 (если это еще не так).
  4. Результат должен выглядеть следующим образом:

    Теперь отображается объект

Глава 10. Тестирование в редакторе Unity

Убедитесь, что настройка сцены правильно реализована.

Убедитесь в следующем:

  • Все скрипты прикрепляются к объекту Main Camera .
  • Все поля на панели инспектора основной камеры назначены правильно.
  1. Нажмите кнопку Воспроизвести в редакторе Unity. Приложение должно выполняться в подключенной иммерсивной гарнитуре.

  2. Попробуйте несколько речевых фрагментов, например:

    make the cylinder red
    
    change the cube to yellow
    
    I want the sphere blue
    
    make this to green
    
    change it to white
    

    Примечание

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

Глава 11. Сборка и загрузка неопубликованного решения UWP

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

Для сборки:

  1. Сохраните текущую сцену, щелкнув Сохранить файл>.

  2. Перейдите в раздел Параметры сборки файла>.

  3. Установите флажок Unity C# Projects (полезно для просмотра и отладки кода после создания проекта UWP).

  4. Щелкните Add Open Scenes (Добавить открытые сцены), а затем щелкните Build (Сборка).

    Окно параметров сборки

  5. Вам будет предложено выбрать папку, в которой вы хотите создать решение.

  6. Создайте папку BUILDS и создайте в ней другую папку с нужным именем.

  7. Щелкните Выбрать папку , чтобы начать сборку в этом расположении.

    Создать папкусборок Выберите папку сборок

  8. После завершения сборки Unity (это может занять некоторое время), оно должно открыть окно проводник в расположении сборки.

Для развертывания на локальном компьютере:

  1. В Visual Studio откройте файл решения, созданный в предыдущей главе.

  2. В окне Платформа решения выберите x86, Локальный компьютер.

  3. В разделе Конфигурация решения выберите Отладка.

    Для Microsoft HoloLens может оказаться проще установить значение Удаленный компьютер, чтобы не привязаться к компьютеру. Однако вам также потребуется выполнить следующие действия.

    • Узнайте IP-адрес holoLens, который можно найти в разделе Параметры > сети & Internet > Wi-Fi > Дополнительные параметры. IPv4 — это адрес, который следует использовать.
    • Убедитесь, что режим разработчикавключен; находится в разделе Параметры Обновление > & безопасность > для разработчиков.

    Развертывание приложения

  4. Перейдите в меню Сборка и щелкните Развернуть решение , чтобы загрузить неопубликованное приложение на компьютер.

  5. Ваше приложение должно появиться в списке установленных приложений, готовых к запуску!

  6. После запуска приложение предложит вам авторизовать доступ к микрофону. Используйте контроллеры движения, голосовой ввод или клавиатуру , чтобы нажать кнопку ДА .

Глава 12. Улучшение службы LUIS

Важно!

Эта глава чрезвычайно важна, и, возможно, потребуется выполнить итерации несколько раз, так как она поможет повысить точность службы LUIS: убедитесь, что вы завершите это.

Чтобы повысить уровень понимания, предоставляемый LUIS, необходимо записать новые речевые фрагменты и использовать их для повторного обучения приложения LUIS.

Например, вы могли обучить LUIS понимать слова "Увеличить" и "Увеличить", но не хотите ли вы, чтобы ваше приложение также понимало такие слова, как "Увеличить"?

После использования приложения несколько раз все, что вы сказали, будет собрано LUIS и будет доступно на ПОРТАЛе LUIS.

  1. Перейдите к приложению портала по этой ссылке и выполните вход.

  2. После входа с учетными данными MS щелкните имя приложения.

  3. Нажмите кнопку Просмотр речевых фрагментов конечной точки в левой части страницы.

    Просмотр речевых фрагментов

  4. Отобразится список высказываний, которые были отправлены в LUIS приложением смешанной реальности.

    Список речевых фрагментов

Вы заметите некоторые выделенные сущности.

Наведите указатель мыши на каждое выделенное слово, чтобы просмотреть каждое высказывание и определить, какая сущность распознана правильно, какие сущности неверны, а какие — пропущены.

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

Удаление образа метки для проверки речевых фрагментов

  1. Если вы нашли совершенно неправильные речевые фрагменты, их можно удалить с помощью кнопки Удалить в правой части экрана.

    Удаление неправильных речевых фрагментов

  2. Или если вы считаете, что LUIS правильно интерпретировал высказывание, вы можете проверить его понимание с помощью кнопки Добавить в выровненное намерение .

    Добавление в выровненное намерение

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

  4. Очень важно повторять этот процесс как можно больше раз, чтобы улучшить понимание приложения.

Желаю удачи!

Готовое интегрированное приложение LUIS

Поздравляем! Вы создали приложение смешанной реальности, которое использует Azure Распознавание речи Intelligence Service, чтобы понять, что говорит пользователь, и действовать с учетом этой информации.

Результат лаборатории

Дополнительные упражнения

Упражнение 1.

При использовании этого приложения вы можете заметить, что если вы посмотрите на объект Floor и попросите изменить его цвет, он сделает это. Можете ли вы поработать с тем, как запретить приложению изменять цвет пола?

Упражнение 2

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