Поделиться через


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 Распознавание речи Интеллектуальной службы (LUIS).
  3. Извлеките LUIS значение из сведений о отправке, которые будут проанализированы, и попытайтесь определить намерение запроса пользователя.

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

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

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

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

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

Примечание.

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

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

Примечание.

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

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

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

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

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

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

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

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

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

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

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

    Примечание.

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

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

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

    Примечание.

    Возможно, слово New было заменено на создание ресурса на более новых порталах.

  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. После нажатия клавиши Done вы введете страницу сборки нового приложения LUIS .

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

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

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

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

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

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

  2. Вызовите новый цвет сущности, задайте его тип Simple, а затем нажмите кнопку "Готово".

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

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

    • upsize
    • сокращать
    • целевой объект

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

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

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

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

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

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

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

  2. Вызовите новый объект Intent 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. Теперь щелкните слово красным в первой фразе и выберите цвет.

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

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

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

    Совет

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

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

    Примечание.

    Для переключения между сущностями и представлениями токенов можно использовать кнопку представления маркеров.

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

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

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

    Обучение LUIS

  7. В качестве упражнения создайте новое намерение с именем ChangeObjectSize, используя целевые объекты, 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 нажмите кнопку PUBLISH в верхней части страницы.

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

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

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

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

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

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

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

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

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

    Внимание

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

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

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

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

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

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

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

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

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

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

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

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

    1. Целевое устройство имеет значение Any Device

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

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

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

    4. Версия Visual Studio установлена в качестве последней версии

    5. Для сборки и запуска задано значение Local Machine

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

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

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

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

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

      3. Откройте только что созданную папку "Сцены" , а затем в поле "Файл": текстовое поле, введите MR_LuisScene, а затем нажмите клавишу SAVE.

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

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

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

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

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

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

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

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

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

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

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

      1. InternetClient;

      2. Микрофон

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

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

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

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

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

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

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

Внимание

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

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

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

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

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

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

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

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

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

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

  7. Выполните поиск компонента с именем "Источник звука", как показано выше.

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

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

    Примечание.

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

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

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

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

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

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

X Y Z
0 1 4

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

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

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

X Y Z
-2 6 9

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

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

  2. Измените имя объекта Text Mesh на Dictation Text.

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

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

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

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

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

Глава 5. Создание класса МикрофонManager

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

Класс МикрофонManager отвечает за следующее:

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

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

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

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

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

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

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

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

        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. Не забудьте сохранить изменения в Visual Studio , прежде чем вернуться в Unity.

    Примечание.

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

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

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

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

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

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

  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. Теперь вам нужны методы, которые используются для отправки диктовки, полученной из класса МикрофонManager в LUIS, а затем получения и десериализации ответа.

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

        /// <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(), который считывает результирующий АнализQuery и определяет сущности. После определения этих сущностей они будут переданы экземпляру класса "Поведение", который будет использоваться в действиях.

        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. Не забудьте сохранить изменения в Visual Studio , прежде чем вернуться в Unity.

Примечание.

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

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

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

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

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

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

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

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

        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(), чтобы определить, какой из gameObjects является целевым объектом текущего намерения. Этот метод по умолчанию использует целевой объект 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. Не забудьте сохранить изменения в Visual Studio , прежде чем вернуться в Unity.

Глава 8. Создание класса Взгляда

Последний класс, который вам потребуется выполнить, — это класс 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. Не забудьте сохранить изменения в Visual Studio , прежде чем вернуться в Unity.

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

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

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

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

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

    1. МикрофонManager:

      • На панели иерархии перетащите объект "Текст диктовки" в поле значения параметра диктовки.
    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# (полезно для просмотра и отладки кода после создания проекта UWP.

  4. Нажмите кнопку "Добавить открытые сцены", а затем нажмите кнопку "Создать".

    Окно

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

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

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

    Создание папки buildsВыбор папки

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

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

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

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

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

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

    • Ознакомься с IP-адресом HoloLens, который можно найти в > разделе "Параметры сети" и "Расширенные параметры Интернета > Wi-Fi>".IPv4 — это адрес, который следует использовать.
    • Убедитесь, что режим разработчика включен; в разделе "Параметры > обновления" и "Безопасность > для разработчиков".

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

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

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

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

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

Внимание

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

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

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

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

  1. Перейдите к приложению портала с помощью этой ССЫЛКИ и войдите в систему.

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

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

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

  4. Вы увидите список речевых фрагментов, отправленных в LUIS приложением смешанной реальности.

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

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

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

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

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

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

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

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

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

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

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

Веселитесь!

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

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

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

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

Упражнение 1

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

Упражнение 2

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