Краткое руководство. Создание проекта обнаружения объектов с помощью клиентской библиотеки Пользовательское визуальное распознавание

Начало работы с клиентской библиотекой "Пользовательское визуальное распознавание" для .NET. Выполните приведенные здесь действия, чтобы установить пакет и протестировать пример кода для сборки модели обнаружения объектов. Здесь объясняется, как создать проект, добавить теги, обучить проект в примерах изображений и использовать URL-адрес конечной точки прогнозирования проекта для тестирования программными средствами. Этот пример можно использовать как шаблон при создании собственного приложения для распознавания изображений.

Примечание.

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

Справочная документация | Исходный код библиотеки (обучение)(прогноз) | Пакет (NuGet) (обучение)(прогноз) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • IDE Visual Studio или текущая версия .NET Core.
  • После получения подписки Azure создайте ресурс Пользовательское визуальное распознавание в портал Azure, чтобы создать обучающий и прогнозирующий ресурс.
    • Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

Создание переменной среды

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

Переход на портал Azure. Если Пользовательское визуальное распознавание ресурсы, созданные в разделе предварительных требований, развернуты успешно, нажмите кнопку "Перейти к ресурсу" в разделе "Дальнейшие действия". Ключи и конечные точки можно найти на страницах ключей и конечных точек ресурсов в разделе управления ресурсами. Вам потребуется получить ключи для ресурсов обучения и прогнозирования, а также конечных точек API.

Идентификатор ресурса прогнозирования можно найти на вкладке "Свойства" ресурса прогнозирования в портал Azure, указанном в качестве идентификатора ресурса.

Совет

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

Внимание

Не включайте ключ непосредственно в код и никогда не публикуйте его. Дополнительные варианты проверки подлинности, такие как Azure Key Vault, см. в статье по безопасности служб ИИ Azure.

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

  1. Чтобы задать VISION_TRAINING KEY переменную среды, замените your-training-key одним из ключей для учебного ресурса.
  2. Чтобы задать переменную среды, замените your-training-endpoint конечной VISION_TRAINING_ENDPOINT точкой для ресурса обучения.
  3. Чтобы задать VISION_PREDICTION_KEY переменную среды, замените your-prediction-key одним из ключей для ресурса прогнозирования.
  4. Чтобы задать переменную среды, замените your-prediction-endpoint конечной VISION_PREDICTION_ENDPOINT точкой для ресурса прогнозирования.
  5. Чтобы задать VISION_PREDICTION_RESOURCE_ID переменную среды, замените your-resource-id идентификатор ресурса для ресурса прогнозирования.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id

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

Установка

Создание нового приложения C#

С помощью Visual Studio создайте приложение .NET Core.

Установка клиентской библиотеки

После создания проекта установите клиентскую библиотеку, щелкнув правой кнопкой мыши решение проекта в Обозревателе решений и выбрав пункт Управление пакетами NuGet. В открывшемся диспетчере пакетов выберите Просмотр, установите флажок Включить предварительные версии и выполните поиск по запросу Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training и Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Выберите последнюю версию и затем нажмите Установка.

Совет

Хотите просмотреть готовый файл с кодом для этого краткого руководства? Его можно найти на сайте GitHub, где размещены примеры кода для этого краткого руководства.

В каталоге проекта откройте файл program.cs и с помощью using добавьте следующие директивы:

using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;

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

    string trainingEndpoint = Environment.GetEnvironmentVariable("VISION_TRAINING_ENDPOINT");

    string trainingKey = Environment.GetEnvironmentVariable("VISION_TRAINING_KEY");
    string predictionEndpoint = Environment.GetEnvironmentVariable("VISION_PREDICTION_ENDPOINT");
    string predictionKey = Environment.GetEnvironmentVariable("VISION_PREDICTION_KEY");

    private static Iteration iteration;
    private static string publishedModelName = "CustomODModel";

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

CustomVisionTrainingClient trainingApi = AuthenticateTraining(trainingEndpoint, trainingKey);
CustomVisionPredictionClient predictionApi = AuthenticatePrediction(predictionEndpoint, predictionKey);

Project project = CreateProject(trainingApi);
AddTags(trainingApi, project);
UploadImages(trainingApi, project);
TrainProject(trainingApi, project);
PublishIteration(trainingApi, project);
TestIteration(predictionApi, project);

аутентификация клиента;

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

private CustomVisionTrainingClient AuthenticateTraining(string endpoint, string trainingKey, string predictionKey)
{
    // Create the Api, passing in the training key
    CustomVisionTrainingClient trainingApi = new CustomVisionTrainingClient(new Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.ApiKeyServiceClientCredentials(trainingKey))
    {
        Endpoint = endpoint
    };
    return trainingApi;
}
private CustomVisionPredictionClient AuthenticatePrediction(string endpoint, string predictionKey)
{
    // Create a prediction endpoint, passing in the obtained prediction key
    CustomVisionPredictionClient predictionApi = new CustomVisionPredictionClient(new Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction.ApiKeyServiceClientCredentials(predictionKey))
    {
        Endpoint = endpoint
    };
    return predictionApi;
}

Создание проекта службы "Пользовательское визуальное распознавание"

Следующий метод создает проект обнаружения объектов. Созданный проект будет отображаться на веб-сайте Пользовательской службы визуального распознавания. Ознакомьтесь с методом CreateProject, чтобы указать другие параметры при создании проекта (см. пояснения в руководстве по созданию средства обнаружения объектов с помощью веб-портала).

private Project CreateProject(CustomVisionTrainingClient trainingApi)
{
    // Find the object detection domain
    var domains = trainingApi.GetDomains();
    var objDetectionDomain = domains.FirstOrDefault(d => d.Type == "ObjectDetection");

    // Create a new project
    Console.WriteLine("Creating new project:");
    project = trainingApi.CreateProject("My New Project", null, objDetectionDomain.Id);

    return project;
}

Добавление тегов в проект

Этот метод определяет теги, по которым вы будете обучать модель.

private void AddTags(CustomVisionTrainingClient trainingApi, Project project)
{
    // Make two tags in the new project
    var forkTag = trainingApi.CreateTag(project.Id, "fork");
    var scissorsTag = trainingApi.CreateTag(project.Id, "scissors");
}

Отправка и снабжение тегами изображений

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

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

private void UploadImages(CustomVisionTrainingClient trainingApi, Project project)
{
    Dictionary<string, double[]> fileToRegionMap = new Dictionary<string, double[]>()
    {
        // FileName, Left, Top, Width, Height
        {"scissors_1", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 } },
        {"scissors_2", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 } },
        {"scissors_3", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 } },
        {"scissors_4", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 } },
        {"scissors_5", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 } },
        {"scissors_6", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 } },
        {"scissors_7", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 } },
        {"scissors_8", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 } },
        {"scissors_9", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 } },
        {"scissors_10", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 } },
        {"scissors_11", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 } },
        {"scissors_12", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 } },
        {"scissors_13", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 } },
        {"scissors_14", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 } },
        {"scissors_15", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 } },
        {"scissors_16", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 } },
        {"scissors_17", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 } },
        {"scissors_18", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 } },
        {"scissors_19", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 } },
        {"scissors_20", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 } },
        {"fork_1", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 } },
        {"fork_2", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 } },
        {"fork_3", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 } },
        {"fork_4", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 } },
        {"fork_5", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 } },
        {"fork_6", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 } },
        {"fork_7", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 } },
        {"fork_8", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 } },
        {"fork_9", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 } },
        {"fork_10", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 } },
        {"fork_11", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 } },
        {"fork_12", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 } },
        {"fork_13", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 } },
        {"fork_14", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 } },
        {"fork_15", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 } },
        {"fork_16", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 } },
        {"fork_17", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 } },
        {"fork_18", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 } },
        {"fork_19", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 } },
        {"fork_20", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 } }
    };

Примечание.

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

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

    // Add all images for fork
    var imagePath = Path.Combine("Images", "fork");
    var imageFileEntries = new List<ImageFileCreateEntry>();
    foreach (var fileName in Directory.EnumerateFiles(imagePath))
    {
        var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
        imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List<Region>(new Region[] { new Region(forkTag.Id, region[0], region[1], region[2], region[3]) })));
    }
    trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));

    // Add all images for scissors
    imagePath = Path.Combine("Images", "scissors");
    imageFileEntries = new List<ImageFileCreateEntry>();
    foreach (var fileName in Directory.EnumerateFiles(imagePath))
    {
        var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
        imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List<Region>(new Region[] { new Region(scissorsTag.Id, region[0], region[1], region[2], region[3]) })));
    }
    trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));
}

На этом этапе вы передали все примеры изображений и пометили каждый из них (вилка или ножницы) со связанным пиксельным прямоугольником.

Обучение проекта

Этот метод создает первую обучающую итерацию в проекте. Он отправляет запрос в службу до завершения обучения.

private void TrainProject(CustomVisionTrainingClient trainingApi, Project project)
{

    // Now there are images with tags start training the project
    Console.WriteLine("\tTraining");
    iteration = trainingApi.TrainProject(project.Id);

    // The returned iteration will be in progress, and can be queried periodically to see when it has completed
    while (iteration.Status == "Training")
    {
        Thread.Sleep(1000);

        // Re-query the iteration to get its updated status
        iteration = trainingApi.GetIteration(project.Id, iteration.Id);
    }
}

Совет

Обучение с использованием выбранных тегов

При необходимости вы можете выполнить обучение с использованием только некоторых из примененных тегов. Это может потребоваться, если вы еще не применили достаточное количество определенных тегов, но у вас достаточно других. В вызове TrainProject используйте параметр trainingParameters. Создайте TrainingParameters и задайте для свойства SelectedTags список идентификаторов тегов, которые хотите использовать. Модель будет обучаться с распознаванием только тегов в этом списке.

Публикация текущей итерации

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

private void PublishIteration(CustomVisionTrainingClient trainingApi, Project project)
{

    // The iteration is now trained. Publish it to the prediction end point.
    var predictionResourceId = Environment.GetEnvironmentVariable("VISION_PREDICTION_RESOURCE_ID");
    trainingApi.PublishIteration(project.Id, iteration.Id, publishedModelName, predictionResourceId);
    Console.WriteLine("Done!\n");
}

Тестирование конечной точки прогнозирования

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

private void TestIteration(CustomVisionPredictionClient predictionApi, Project project)
{

    // Make a prediction against the new project
    Console.WriteLine("Making a prediction:");
    var imageFile = Path.Combine("Images", "test", "test_image.jpg");
    using (var stream = File.OpenRead(imageFile))
    {
        var result = predictionApi.DetectImage(project.Id, publishedModelName, stream);

        // Loop over each prediction and write out the results
        foreach (var c in result.Predictions)
        {
            Console.WriteLine($"\t{c.TagName}: {c.Probability:P1} [ {c.BoundingBox.Left}, {c.BoundingBox.Top}, {c.BoundingBox.Width}, {c.BoundingBox.Height} ]");
        }
    }
    Console.ReadKey();
}

Выполнение приложения

Запустите приложение, нажав кнопку Отладка в верхней части окна интегрированной среды разработки.

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

Creating new project:
        Training
Done!

Making a prediction:
        fork: 98.2% [ 0.111609578, 0.184719115, 0.6607002, 0.6637112 ]
        scissors: 1.2% [ 0.112389535, 0.119195729, 0.658031344, 0.7023591 ]

Вы можете убедиться, что тестовое изображение (в Images/Test/) помечено соответствующим образом и что область обнаружения верна. На этом этапе нажмите любую клавишу для выхода из приложения.

Очистка ресурсов

Если нужно реализовать собственный проект распознавания объектов (или использовать вместо него проект классификации изображений), вы можете удалить проект распознавания вилок и ножниц из этого примера. При работе в бесплатной подписке на Пользовательское визуальное распознавание можно создать два проекта.

На веб-сайте Пользовательской службы визуального распознавания перейдите в раздел проектов и щелкните значок корзины под заголовком "My New Project" (Мой новый проект).

Screenshot of a panel labeled My New Project with a trash can icon.

Следующие шаги

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

Это руководство содержит инструкции и пример кода, которые помогут вам приступить к работе с клиентской библиотекой службы "Пользовательское визуальное распознавание" для Go и создать модель обнаружения объекта. Здесь объясняется, как создать проект, добавить теги, обучить проект и использовать URL-адрес конечной точки прогнозирования проекта для программного тестирования. Этот пример можно использовать как шаблон при создании собственного приложения для распознавания изображений.

Примечание.

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

Используйте клиентскую библиотеку службы "Пользовательское визуальное распознавание" для Go, чтобы выполнять такие действия:

  • Создание проекта службы "Пользовательское визуальное распознавание"
  • Добавление тегов в проект
  • Отправка и снабжение тегами изображений
  • Обучение проекта
  • Публикация текущей итерации
  • Тестирование конечной точки прогнозирования

Справочная документация (обучение)(прогнозирование)

Необходимые компоненты

Создание переменной среды

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

Переход на портал Azure. Если Пользовательское визуальное распознавание ресурсы, созданные в разделе предварительных требований, развернуты успешно, нажмите кнопку "Перейти к ресурсу" в разделе "Дальнейшие действия". Ключи и конечные точки можно найти на страницах ключей и конечных точек ресурсов в разделе управления ресурсами. Вам потребуется получить ключи для ресурсов обучения и прогнозирования, а также конечных точек API.

Идентификатор ресурса прогнозирования можно найти на вкладке "Свойства" ресурса прогнозирования в портал Azure, указанном в качестве идентификатора ресурса.

Совет

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

Внимание

Не включайте ключ непосредственно в код и никогда не публикуйте его. Дополнительные варианты проверки подлинности, такие как Azure Key Vault, см. в статье по безопасности служб ИИ Azure.

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

  1. Чтобы задать VISION_TRAINING KEY переменную среды, замените your-training-key одним из ключей для учебного ресурса.
  2. Чтобы задать переменную среды, замените your-training-endpoint конечной VISION_TRAINING_ENDPOINT точкой для ресурса обучения.
  3. Чтобы задать VISION_PREDICTION_KEY переменную среды, замените your-prediction-key одним из ключей для ресурса прогнозирования.
  4. Чтобы задать переменную среды, замените your-prediction-endpoint конечной VISION_PREDICTION_ENDPOINT точкой для ресурса прогнозирования.
  5. Чтобы задать VISION_PREDICTION_RESOURCE_ID переменную среды, замените your-resource-id идентификатор ресурса для ресурса прогнозирования.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id

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

Установка

Установка клиентской библиотеки Пользовательского визуального распознавания

Чтобы написать приложение для анализа изображений с помощью службы "Пользовательское визуальное распознавание" для Go, вам потребуется клиентская библиотека этой службы. Выполните следующую команду в PowerShell:

go get -u github.com/Azure/azure-sdk-for-go/...

Или, если вы используете dep, выполните в репозитории следующую команду:

dep ensure -add github.com/Azure/azure-sdk-for-go

Получение примеров изображений

В этом примере используются образы из репозитория примеров пакета SDK для Python служб ИИ Azure на GitHub. Клонируйте или скачайте этот репозиторий в свою среду разработки. Запомните расположение папки. Оно потребуется в дальнейшем.

Создание проекта в службе "Пользовательское визуальное распознавание"

Создайте файл с именем sample.go в предпочтительном каталоге проекта и откройте его в редакторе кода.

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

Ознакомьтесь с методом CreateProject, чтобы указать другие параметры при создании проекта (см. пояснения в руководстве по созданию средства обнаружения объектов с помощью веб-портала).

import(
    "context"
    "bytes"
    "fmt"
    "io/ioutil"
    "path"
    "log"
    "time"
    "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v3.0/customvision/training"
    "github.com/Azure/azure-sdk-for-go/services/cognitiveservices/v3.0/customvision/prediction"
)

// retrieve environment variables:
var (
    training_key string = os.Getenv("VISION_TRAINING_KEY")
    prediction_key string = os.Getenv("VISION_PREDICTION_KEY")
    prediction_resource_id = os.Getenv("VISION_PREDICTION_RESOURCE_ID")
    endpoint string = os.Getenv("VISION_ENDPOINT")
   
    project_name string = "Go Sample OD Project"
    iteration_publish_name = "detectModel"
    sampleDataDirectory = "<path to sample images>"
)

func main() {
    fmt.Println("Creating project...")

    ctx = context.Background()

    trainer := training.New(training_key, endpoint)

    var objectDetectDomain training.Domain
    domains, _ := trainer.GetDomains(ctx)

    for _, domain := range *domains.Value {
        fmt.Println(domain, domain.Type)
        if domain.Type == "ObjectDetection" && *domain.Name == "General" {
            objectDetectDomain = domain
            break
        }
    }
    fmt.Println("Creating project...")
    project, _ := trainer.CreateProject(ctx, project_name, "", objectDetectDomain.ID, "")

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

Чтобы создать теги классификации в проекте, добавьте в конец sample.go следующий код:

# Make two tags in the new project
forkTag, _ := trainer.CreateTag(ctx, *project.ID, "fork", "A fork", string(training.Regular))
scissorsTag, _ := trainer.CreateTag(ctx, *project.ID, "scissors", "Pair of scissors", string(training.Regular))

Отправка и снабжение тегами изображений

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

Примечание.

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

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

forkImageRegions := map[string][4]float64{
    "fork_1.jpg": [4]float64{ 0.145833328, 0.3509314, 0.5894608, 0.238562092 },
    "fork_2.jpg": [4]float64{ 0.294117659, 0.216944471, 0.534313738, 0.5980392 },
    "fork_3.jpg": [4]float64{ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 },
    "fork_4.jpg": [4]float64{ 0.254901975, 0.185898721, 0.5232843, 0.594771266 },
    "fork_5.jpg": [4]float64{ 0.2365196, 0.128709182, 0.5845588, 0.71405226 },
    "fork_6.jpg": [4]float64{ 0.115196079, 0.133611143, 0.676470637, 0.6993464 },
    "fork_7.jpg": [4]float64{ 0.164215669, 0.31008172, 0.767156839, 0.410130739 },
    "fork_8.jpg": [4]float64{ 0.118872553, 0.318251669, 0.817401946, 0.225490168 },
    "fork_9.jpg": [4]float64{ 0.18259804, 0.2136765, 0.6335784, 0.643790841 },
    "fork_10.jpg": [4]float64{ 0.05269608, 0.282303959, 0.8088235, 0.452614367 },
    "fork_11.jpg": [4]float64{ 0.05759804, 0.0894935, 0.9007353, 0.3251634 },
    "fork_12.jpg": [4]float64{ 0.3345588, 0.07315363, 0.375, 0.9150327 },
    "fork_13.jpg": [4]float64{ 0.269607842, 0.194068655, 0.4093137, 0.6732026 },
    "fork_14.jpg": [4]float64{ 0.143382356, 0.218578458, 0.7977941, 0.295751631 },
    "fork_15.jpg": [4]float64{ 0.19240196, 0.0633497, 0.5710784, 0.8398692 },
    "fork_16.jpg": [4]float64{ 0.140931368, 0.480016381, 0.6838235, 0.240196079 },
    "fork_17.jpg": [4]float64{ 0.305147052, 0.2512582, 0.4791667, 0.5408496 },
    "fork_18.jpg": [4]float64{ 0.234068632, 0.445702642, 0.6127451, 0.344771236 },
    "fork_19.jpg": [4]float64{ 0.219362751, 0.141781077, 0.5919118, 0.6683006 },
    "fork_20.jpg": [4]float64{ 0.180147052, 0.239820287, 0.6887255, 0.235294119 },
}

scissorsImageRegions := map[string][4]float64{
    "scissors_1.jpg": [4]float64{ 0.4007353, 0.194068655, 0.259803921, 0.6617647 },
    "scissors_2.jpg": [4]float64{ 0.426470578, 0.185898721, 0.172794119, 0.5539216 },
    "scissors_3.jpg": [4]float64{ 0.289215684, 0.259428144, 0.403186262, 0.421568632 },
    "scissors_4.jpg": [4]float64{ 0.343137264, 0.105833367, 0.332107842, 0.8055556 },
    "scissors_5.jpg": [4]float64{ 0.3125, 0.09766343, 0.435049027, 0.71405226 },
    "scissors_6.jpg": [4]float64{ 0.379901975, 0.24308826, 0.32107842, 0.5718954 },
    "scissors_7.jpg": [4]float64{ 0.341911763, 0.20714055, 0.3137255, 0.6356209 },
    "scissors_8.jpg": [4]float64{ 0.231617644, 0.08459154, 0.504901946, 0.8480392 },
    "scissors_9.jpg": [4]float64{ 0.170343131, 0.332957536, 0.767156839, 0.403594762 },
    "scissors_10.jpg": [4]float64{ 0.204656869, 0.120539248, 0.5245098, 0.743464053 },
    "scissors_11.jpg": [4]float64{ 0.05514706, 0.159754932, 0.799019635, 0.730392158 },
    "scissors_12.jpg": [4]float64{ 0.265931368, 0.169558853, 0.5061275, 0.606209159 },
    "scissors_13.jpg": [4]float64{ 0.241421565, 0.184264734, 0.448529422, 0.6830065 },
    "scissors_14.jpg": [4]float64{ 0.05759804, 0.05027781, 0.75, 0.882352948 },
    "scissors_15.jpg": [4]float64{ 0.191176474, 0.169558853, 0.6936275, 0.6748366 },
    "scissors_16.jpg": [4]float64{ 0.1004902, 0.279036, 0.6911765, 0.477124184 },
    "scissors_17.jpg": [4]float64{ 0.2720588, 0.131977156, 0.4987745, 0.6911765 },
    "scissors_18.jpg": [4]float64{ 0.180147052, 0.112369314, 0.6262255, 0.6666667 },
    "scissors_19.jpg": [4]float64{ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 },
    "scissors_20.jpg": [4]float64{ 0.158088237, 0.04047389, 0.6691176, 0.843137264 },
}

Затем используйте карту ассоциаций, чтобы передать каждый пример изображения с его координатами региона (можно передать до 64 изображений в одном пакете). Добавьте следующий код.

Примечание.

Вам потребуется изменить путь к изображениям на основе того, где вы скачали проект azure AI Services Go SDK Samples.

// Go through the data table above and create the images
fmt.Println("Adding images...")
var fork_images []training.ImageFileCreateEntry
for file, region := range forkImageRegions {
    imageFile, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "fork", file))

    regiontest := forkImageRegions[file]
    imageRegion := training.Region{
        TagID:  forkTag.ID,
        Left:   &regiontest[0],
        Top:    &regiontest[1],
        Width:  &regiontest[2],
        Height: &regiontest[3],
    }
    var fileName string = file

    fork_images = append(fork_images, training.ImageFileCreateEntry{
        Name:     &fileName,
        Contents: &imageFile,
        Regions:  &[]training.Region{imageRegion}
    })
}
    
fork_batch, _ := trainer.CreateImagesFromFiles(ctx, *project.ID, training.ImageFileCreateBatch{ 
    Images: &fork_images,
})

if (!*fork_batch.IsBatchSuccessful) {
    fmt.Println("Batch upload failed.")
}

var scissor_images []training.ImageFileCreateEntry
for file, region := range scissorsImageRegions {
    imageFile, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "scissors", file))

    imageRegion := training.Region { 
        TagID:scissorsTag.ID,
        Left:&region[0],
        Top:&region[1],
        Width:&region[2],
        Height:&region[3],
    }

    scissor_images = append(scissor_images, training.ImageFileCreateEntry {
        Name: &file,
        Contents: &imageFile,
        Regions: &[]training.Region{ imageRegion },
    })
}
    
scissor_batch, _ := trainer.CreateImagesFromFiles(ctx, *project.ID, training.ImageFileCreateBatch{ 
    Images: &scissor_images,
})
    
if (!*scissor_batch.IsBatchSuccessful) {
    fmt.Println("Batch upload failed.")
}     

Обучение и публикация проекта

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

iteration, _ := trainer.TrainProject(ctx, *project.ID)
fmt.Println("Training status:", *iteration.Status)
for {
    if *iteration.Status != "Training" {
        break
    }
    time.Sleep(5 * time.Second)
    iteration, _ = trainer.GetIteration(ctx, *project.ID, *iteration.ID)
    fmt.Println("Training status:", *iteration.Status)
}

trainer.PublishIteration(ctx, *project.ID, *iteration.ID, iteration_publish_name, prediction_resource_id))

Использование конечной точки прогнозирования

Чтобы отправить изображение в конечную точку прогнозирования и извлечь прогнозирование, добавьте в конец файла следующий код:

    fmt.Println("Predicting...")
    predictor := prediction.New(prediction_key, endpoint)

    testImageData, _ := ioutil.ReadFile(path.Join(sampleDataDirectory, "Test", "test_od_image.jpg"))
    results, _ := predictor.DetectImage(ctx, *project.ID, iteration_publish_name, ioutil.NopCloser(bytes.NewReader(testImageData)), "")

    for _, prediction := range *results.Predictions    {
        boundingBox := *prediction.BoundingBox

        fmt.Printf("\t%s: %.2f%% (%.2f, %.2f, %.2f, %.2f)", 
            *prediction.TagName,
            *prediction.Probability * 100,
            *boundingBox.Left,
            *boundingBox.Top,
            *boundingBox.Width,
            *boundingBox.Height)
        fmt.Println("")
    }
}

Выполнение приложения

Выполните sample.go.

go run sample.go

Выходные данные приложения должны появиться в консоли. Вы можете убедиться, что тестовое изображение (в samples/vision/images/Test/) помечено соответствующим образом и что область обнаружения верна.

Очистка ресурсов

Если нужно реализовать собственный проект распознавания объектов (или использовать вместо него проект классификации изображений), вы можете удалить проект распознавания вилок и ножниц из этого примера. При работе в бесплатной подписке на Пользовательское визуальное распознавание можно создать два проекта.

На веб-сайте Пользовательской службы визуального распознавания перейдите в раздел проектов и щелкните значок корзины под заголовком "My New Project" (Мой новый проект).

Screenshot of a panel labeled My New Project with a trash can icon.

Следующие шаги

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

Сведения о том, как начать работу с клиентской библиотекой Пользовательского визуального распознавания для Java и создать модель обнаружения объектов. Выполните приведенные здесь действия, чтобы установить пакет и протестировать пример кода для выполнения базовых задач. Этот пример можно использовать как шаблон при создании собственного приложения для распознавания изображений.

Примечание.

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

Используйте клиентскую библиотеку Пользовательского визуального распознавания для Java, чтобы выполнять такие задачи:

  • Создание проекта службы "Пользовательское визуальное распознавание"
  • Добавление тегов в проект
  • Отправка и снабжение тегами изображений
  • Обучение проекта
  • Публикация текущей итерации
  • Тестирование конечной точки прогнозирования

Справочная документация | Исходный код библиотеки (обучение)(прогноз) | Артефакт (Maven) (обучение)(прогноз) | Примеры

Необходимые компоненты

Создание переменной среды

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

Переход на портал Azure. Если Пользовательское визуальное распознавание ресурсы, созданные в разделе предварительных требований, развернуты успешно, нажмите кнопку "Перейти к ресурсу" в разделе "Дальнейшие действия". Ключи и конечные точки можно найти на страницах ключей и конечных точек ресурсов в разделе управления ресурсами. Вам потребуется получить ключи для ресурсов обучения и прогнозирования, а также конечных точек API.

Идентификатор ресурса прогнозирования можно найти на вкладке "Свойства" ресурса прогнозирования в портал Azure, указанном в качестве идентификатора ресурса.

Совет

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

Внимание

Не включайте ключ непосредственно в код и никогда не публикуйте его. Дополнительные варианты проверки подлинности, такие как Azure Key Vault, см. в статье по безопасности служб ИИ Azure.

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

  1. Чтобы задать VISION_TRAINING KEY переменную среды, замените your-training-key одним из ключей для учебного ресурса.
  2. Чтобы задать переменную среды, замените your-training-endpoint конечной VISION_TRAINING_ENDPOINT точкой для ресурса обучения.
  3. Чтобы задать VISION_PREDICTION_KEY переменную среды, замените your-prediction-key одним из ключей для ресурса прогнозирования.
  4. Чтобы задать переменную среды, замените your-prediction-endpoint конечной VISION_PREDICTION_ENDPOINT точкой для ресурса прогнозирования.
  5. Чтобы задать VISION_PREDICTION_RESOURCE_ID переменную среды, замените your-resource-id идентификатор ресурса для ресурса прогнозирования.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id

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

Установка

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

В окне консоли (например, cmd, PowerShell или Bash) создайте новый каталог для приложения и перейдите в него.

mkdir myapp && cd myapp

Выполните команду gradle init из рабочей папки. Эта команда создает необходимые файлы сборки для Gradle, включая build.gradle.kts, который используется во время выполнения для создания и настройки приложения.

gradle init --type basic

Когда появится запрос на выбор предметно-ориентированного языка, выберите Kotlin.

Установка клиентской библиотеки

Найдите файл build.gradle.kts и откройте его в предпочитаемой интегрированной среде разработки или текстовом редакторе. Затем скопируйте и вставьте в файл приведенную ниже конфигурацию сборки. Эта конфигурация определяет проект как приложение Java, точкой входа которого является класс CustomVisionQuickstart. Он импортирует библиотеки Пользовательского визуального распознавания.

plugins {
    java
    application
}
application { 
    mainClassName = "CustomVisionQuickstart"
}
repositories {
    mavenCentral()
}
dependencies {
    compile(group = "com.azure", name = "azure-cognitiveservices-customvision-training", version = "1.1.0-preview.2")
    compile(group = "com.azure", name = "azure-cognitiveservices-customvision-prediction", version = "1.1.0-preview.2")
}

Создание файла Java

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

mkdir -p src/main/java

Перейдите в новую папку и создайте файл с именем CustomVisionQuickstart.java. Откройте его в предпочитаемом редакторе или интегрированной среде разработки и добавьте следующие операторы import:

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

import com.google.common.io.ByteStreams;

import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Classifier;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Domain;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.DomainType;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.ImageFileCreateBatch;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.ImageFileCreateEntry;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Iteration;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Project;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Region;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.TrainProjectOptionalParameter;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.CustomVisionTrainingClient;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.Trainings;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.CustomVisionTrainingManager;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.models.ImagePrediction;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.models.Prediction;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.CustomVisionPredictionClient;
import com.microsoft.azure.cognitiveservices.vision.customvision.prediction.CustomVisionPredictionManager;
import com.microsoft.azure.cognitiveservices.vision.customvision.training.models.Tag;

Совет

Хотите просмотреть готовый файл с кодом для этого краткого руководства? Его можно найти на сайте GitHub, где размещены примеры кода для этого краткого руководства.

В классе CustomVisionQuickstart приложения создайте переменные, которые извлекают ключи и конечную точку ресурса из переменных среды.

// retrieve environment variables
final static String trainingApiKey = System.getenv("VISION_TRAINING_KEY");
final static String trainingEndpoint = System.getenv("VISION_TRAINING_ENDPOINT");
final static String predictionApiKey = System.getenv("VISION_PREDICTION_KEY");
final static String predictionEndpoint = System.getenv("VISION_PREDICTION_ENDPOINT");
final static String predictionResourceId = System.getenv("VISION_PREDICTION_RESOURCE_ID");

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

Project projectOD = createProjectOD(trainClient);
addTagsOD(trainClient, projectOD);
uploadImagesOD(trainClient, projectOD);
trainProjectOD(trainClient, projectOD);
publishIterationOD(trainClient, project);
testProjectOD(predictor, projectOD);

Объектная модель

Следующие классы и интерфейсы воплощают некоторые основные функции клиентской библиотеки Пользовательского визуального распознавания для Java.

Имя Описание
CustomVisionTrainingClient Этот класс обрабатывает создание, обучение и публикацию ваших моделей.
CustomVisionPredictionClient Этот класс обрабатывает запросы ваших моделей для прогнозов обнаружения объектов.
ImagePrediction Этот класс определяет прогнозирование одного объекта на одном изображении. Он содержит свойства для идентификатора объекта и его имени, расположение ограничивающего прямоугольника объекта и оценку достоверности.

Примеры кода

Эти фрагменты кода показывают, как выполнить следующие действия с помощью клиентской библиотеки службы "Пользовательское визуальное распознавание" для Java:

аутентификация клиента;

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

// Authenticate
CustomVisionTrainingClient trainClient = CustomVisionTrainingManager
        .authenticate(trainingEndpoint, trainingApiKey)
        .withEndpoint(trainingEndpoint);
CustomVisionPredictionClient predictor = CustomVisionPredictionManager
        .authenticate(predictionEndpoint, predictionApiKey)
        .withEndpoint(predictionEndpoint);

Создание проекта службы "Пользовательское визуальное распознавание"

Следующий метод создает проект обнаружения объектов. Созданный проект будет отображаться на веб-сайте Пользовательской службы визуального распознавания, который вы посещали ранее. Ознакомьтесь с перегрузками метода CreateProject, чтобы указать другие параметры при создании проекта (см. пояснения в руководстве по созданию средства обнаружения объектов с помощью веб-портала).

public static Project createProjectOD(CustomVisionTrainingClient trainClient) {
    Trainings trainer = trainClient.trainings();

    // find the object detection domain to set the project type
    Domain objectDetectionDomain = null;
    List<Domain> domains = trainer.getDomains();
    for (final Domain domain : domains) {
        if (domain.type() == DomainType.OBJECT_DETECTION) {
            objectDetectionDomain = domain;
            break;
        }
    }

    if (objectDetectionDomain == null) {
        System.out.println("Unexpected result; no objects were detected.");
    }

    System.out.println("Creating project...");
    // create an object detection project
    Project project = trainer.createProject().withName("Sample Java OD Project")
            .withDescription("Sample OD Project").withDomainId(objectDetectionDomain.id())
            .withClassificationType(Classifier.MULTILABEL.toString()).execute();

    return project;
}

Добавление тегов в проект

Этот метод определяет теги, по которым вы будете обучать модель.

public static void addTagsOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();
    // create fork tag
    Tag forkTag = trainer.createTag().withProjectId(project.id()).withName("fork").execute();

    // create scissors tag
    Tag scissorsTag = trainer.createTag().withProjectId(project.id()).withName("scissor").execute();
}

Отправка и снабжение тегами изображений

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

Примечание.

Вам нужен более широкий набор изображений для выполнения обучения? Trove, проект Microsoft Garage, позволяет создавать и покупать наборы изображений для обучения. После сбора изображений их можно скачать, а затем импортировать в проект Пользовательского визуального распознавания обычным способом. Чтобы узнать больше, посетите страницу Trove.

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

Примечание.

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

public static void uploadImagesOD(CustomVisionTrainingClient trainClient, Project project) {
    // Mapping of filenames to their respective regions in the image. The
    // coordinates are specified
    // as left, top, width, height in normalized coordinates. I.e. (left is left in
    // pixels / width in pixels)

    // This is a hardcoded mapping of the files we'll upload along with the bounding
    // box of the object in the
    // image. The boudning box is specified as left, top, width, height in
    // normalized coordinates.
    // Normalized Left = Left / Width (in Pixels)
    // Normalized Top = Top / Height (in Pixels)
    // Normalized Bounding Box Width = (Right - Left) / Width (in Pixels)
    // Normalized Bounding Box Height = (Bottom - Top) / Height (in Pixels)
    HashMap<String, double[]> regionMap = new HashMap<String, double[]>();
    regionMap.put("scissors_1.jpg", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 });
    regionMap.put("scissors_2.jpg", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 });
    regionMap.put("scissors_3.jpg", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 });
    regionMap.put("scissors_4.jpg", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 });
    regionMap.put("scissors_5.jpg", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 });
    regionMap.put("scissors_6.jpg", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 });
    regionMap.put("scissors_7.jpg", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 });
    regionMap.put("scissors_8.jpg", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 });
    regionMap.put("scissors_9.jpg", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 });
    regionMap.put("scissors_10.jpg", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 });
    regionMap.put("scissors_11.jpg", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 });
    regionMap.put("scissors_12.jpg", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 });
    regionMap.put("scissors_13.jpg", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 });
    regionMap.put("scissors_14.jpg", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 });
    regionMap.put("scissors_15.jpg", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 });
    regionMap.put("scissors_16.jpg", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 });
    regionMap.put("scissors_17.jpg", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 });
    regionMap.put("scissors_18.jpg", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 });
    regionMap.put("scissors_19.jpg", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 });
    regionMap.put("scissors_20.jpg", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 });
    regionMap.put("fork_1.jpg", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 });
    regionMap.put("fork_2.jpg", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 });
    regionMap.put("fork_3.jpg", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 });
    regionMap.put("fork_4.jpg", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 });
    regionMap.put("fork_5.jpg", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 });
    regionMap.put("fork_6.jpg", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 });
    regionMap.put("fork_7.jpg", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 });
    regionMap.put("fork_8.jpg", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 });
    regionMap.put("fork_9.jpg", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 });
    regionMap.put("fork_10.jpg", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 });
    regionMap.put("fork_11.jpg", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 });
    regionMap.put("fork_12.jpg", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 });
    regionMap.put("fork_13.jpg", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 });
    regionMap.put("fork_14.jpg", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 });
    regionMap.put("fork_15.jpg", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 });
    regionMap.put("fork_16.jpg", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 });
    regionMap.put("fork_17.jpg", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 });
    regionMap.put("fork_18.jpg", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 });
    regionMap.put("fork_19.jpg", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 });
    regionMap.put("fork_20.jpg", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 });

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

    Trainings trainer = trainClient.trainings();

    System.out.println("Adding images...");
    for (int i = 1; i <= 20; i++) {
        String fileName = "fork_" + i + ".jpg";
        byte[] contents = GetImage("/fork", fileName);
        AddImageToProject(trainer, project, fileName, contents, forkTag.id(), regionMap.get(fileName));
    }

    for (int i = 1; i <= 20; i++) {
        String fileName = "scissors_" + i + ".jpg";
        byte[] contents = GetImage("/scissors", fileName);
        AddImageToProject(trainer, project, fileName, contents, scissorsTag.id(), regionMap.get(fileName));
    }
}

Предыдущий фрагмент кода применяет две вспомогательные функции, которые извлекают изображения как потоки данных и загружают их в службу (можно передать до 64 изображений в одном пакете). Определите такие методы.

private static void AddImageToProject(Trainings trainer, Project project, String fileName, byte[] contents,
        UUID tag, double[] regionValues) {
    System.out.println("Adding image: " + fileName);
    ImageFileCreateEntry file = new ImageFileCreateEntry().withName(fileName).withContents(contents);

    ImageFileCreateBatch batch = new ImageFileCreateBatch().withImages(Collections.singletonList(file));

    // If Optional region is specified, tack it on and place the tag there,
    // otherwise
    // add it to the batch.
    if (regionValues != null) {
        Region region = new Region().withTagId(tag).withLeft(regionValues[0]).withTop(regionValues[1])
                .withWidth(regionValues[2]).withHeight(regionValues[3]);
        file = file.withRegions(Collections.singletonList(region));
    } else {
        batch = batch.withTagIds(Collections.singletonList(tag));
    }

    trainer.createImagesFromFiles(project.id(), batch);
}

private static byte[] GetImage(String folder, String fileName) {
    try {
        return ByteStreams.toByteArray(CustomVisionSamples.class.getResourceAsStream(folder + "/" + fileName));
    } catch (Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
    return null;
}

Обучение проекта

Этот метод создает первую обучающую итерацию в проекте. Он отправляет запрос в службу до завершения обучения.

public static String trainProjectOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();
    System.out.println("Training...");
    Iteration iteration = trainer.trainProject(project.id(), new TrainProjectOptionalParameter());

    while (iteration.status().equals("Training")) {
        System.out.println("Training Status: " + iteration.status());
        Thread.sleep(5000);
        iteration = trainer.getIteration(project.id(), iteration.id());
    }
    System.out.println("Training Status: " + iteration.status());
}

Публикация текущей итерации

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

public static String publishIterationOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();

    // The iteration is now trained. Publish it to the prediction endpoint.
    String publishedModelName = "myModel";
    String predictionID = "<your-prediction-resource-ID>";
    trainer.publishIteration(project.id(), iteration.id(), publishedModelName, predictionID);
    return publishedModelName;
}

Тестирование конечной точки прогнозирования

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

public static void testProjectOD(CustomVisionPredictionClient predictor, Project project) {

    // load test image
    byte[] testImage = GetImage("/ObjectTest", "test_image.jpg");

    // predict
    ImagePrediction results = predictor.predictions().detectImage().withProjectId(project.id())
            .withPublishedName(publishedModelName).withImageData(testImage).execute();

    for (Prediction prediction : results.predictions()) {
        System.out.println(String.format("\t%s: %.2f%% at: %.2f, %.2f, %.2f, %.2f", prediction.tagName(),
                prediction.probability() * 100.0f, prediction.boundingBox().left(), prediction.boundingBox().top(),
                prediction.boundingBox().width(), prediction.boundingBox().height()));
    }
}

Выполнение приложения

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

gradle build

Запустите приложение, выполнив команду gradle run:

gradle run

Очистка ресурсов

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

Если нужно реализовать собственный проект распознавания объектов (или использовать вместо него проект классификации изображений), вы можете удалить проект распознавания вилок и ножниц из этого примера. При работе в бесплатной подписке на Пользовательское визуальное распознавание можно создать два проекта.

На веб-сайте Пользовательской службы визуального распознавания перейдите в раздел проектов и щелкните значок корзины под заголовком "My New Project" (Мой новый проект).

Screenshot of a panel labeled My New Project with a trash can icon.

Следующие шаги

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

Это руководство содержит инструкции и пример кода, которые помогут вам приступить к работе с клиентской библиотекой Пользовательского визуального распознавания для Node.js и создать модель обнаружения объекта. Здесь объясняется, как создать проект, добавить теги, обучить проект и использовать URL-адрес конечной точки прогнозирования проекта для программного тестирования. Этот пример можно использовать как шаблон при создании собственного приложения для распознавания изображений.

Примечание.

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

Используйте клиентскую библиотеку "Пользовательское визуальное распознавание" для .NET, чтобы выполнять такие действия:

  • Создание проекта службы "Пользовательское визуальное распознавание"
  • Добавление тегов в проект
  • Отправка и снабжение тегами изображений
  • Обучение проекта
  • Публикация текущей итерации
  • Тестирование конечной точки прогнозирования

Справочная документация (обучение)(прогноз) | Исходный код библиотеки (обучение)(прогноз) | Пакет (npm) (обучение)(прогноз) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • Текущая версия Node.js
  • После получения подписки Azure создайте ресурс Пользовательское визуальное распознавание в портал Azure, чтобы создать обучающий и прогнозирующий ресурс.
    • Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

Создание переменной среды

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

Переход на портал Azure. Если Пользовательское визуальное распознавание ресурсы, созданные в разделе предварительных требований, развернуты успешно, нажмите кнопку "Перейти к ресурсу" в разделе "Дальнейшие действия". Ключи и конечные точки можно найти на страницах ключей и конечных точек ресурсов в разделе управления ресурсами. Вам потребуется получить ключи для ресурсов обучения и прогнозирования, а также конечных точек API.

Идентификатор ресурса прогнозирования можно найти на вкладке "Свойства" ресурса прогнозирования в портал Azure, указанном в качестве идентификатора ресурса.

Совет

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

Внимание

Не включайте ключ непосредственно в код и никогда не публикуйте его. Дополнительные варианты проверки подлинности, такие как Azure Key Vault, см. в статье по безопасности служб ИИ Azure.

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

  1. Чтобы задать VISION_TRAINING KEY переменную среды, замените your-training-key одним из ключей для учебного ресурса.
  2. Чтобы задать переменную среды, замените your-training-endpoint конечной VISION_TRAINING_ENDPOINT точкой для ресурса обучения.
  3. Чтобы задать VISION_PREDICTION_KEY переменную среды, замените your-prediction-key одним из ключей для ресурса прогнозирования.
  4. Чтобы задать переменную среды, замените your-prediction-endpoint конечной VISION_PREDICTION_ENDPOINT точкой для ресурса прогнозирования.
  5. Чтобы задать VISION_PREDICTION_RESOURCE_ID переменную среды, замените your-resource-id идентификатор ресурса для ресурса прогнозирования.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id

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

Установка

Создание нового приложения Node.js

В окне консоли (например, cmd, PowerShell или Bash) создайте новый каталог для приложения и перейдите в него.

mkdir myapp && cd myapp

Выполните команду npm init, чтобы создать приложение узла с помощью файла package.json.

npm init

Установка клиентской библиотеки

Чтобы написать приложение для анализа изображений с помощью Пользовательского визуального распознавания для Node.js, вам потребуются пакеты NPM этой службы. Чтобы установить их, выполните в PowerShell следующую команду:

npm install @azure/cognitiveservices-customvision-training
npm install @azure/cognitiveservices-customvision-prediction

Файл package.json этого приложения будет дополнен зависимостями.

Создайте файл с именем index.js и импортируйте следующие библиотеки:

const util = require('util');
const fs = require('fs');
const TrainingApi = require("@azure/cognitiveservices-customvision-training");
const PredictionApi = require("@azure/cognitiveservices-customvision-prediction");
const msRest = require("@azure/ms-rest-js");

Совет

Хотите просмотреть готовый файл с кодом для этого краткого руководства? Его можно найти на сайте GitHub, где размещены примеры кода для этого краткого руководства.

Создайте переменные для конечной точки Azure и ключей ресурса.

// retrieve environment variables
const trainingKey = process.env["VISION_TRAINING_KEY"];
const trainingEndpoint = process.env["VISION_TRAINING_ENDPOINT"];

const predictionKey = process.env["VISION_PREDICTION_KEY"];
const predictionResourceId = process.env["VISION_PREDICTION_RESOURCE_ID"];
const predictionEndpoint = process.env["VISION_PREDICTION_ENDPOINT"];

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

const publishIterationName = "detectModel";
const setTimeoutPromise = util.promisify(setTimeout);

Объектная модель

Имя Описание
TrainingAPIClient Этот класс обрабатывает создание, обучение и публикацию ваших моделей.
PredictionAPIClient Этот класс обрабатывает запросы ваших моделей для прогнозов обнаружения объектов.
Прогноз Этот интерфейс определяет один прогноз для одного изображения. Он содержит свойства идентификатора и имени объекта, а также оценку доверительного уровня.

Примеры кода

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

аутентификация клиента;

Создайте экземпляры клиентских объектов с использованием конечной точки и ключа. Создайте объект ApiKeyCredentials с ключом и используйте его с конечной точкой, чтобы создать объект TrainingAPIClient и PredictionAPIClient.

const credentials = new msRest.ApiKeyCredentials({ inHeader: { "Training-key": trainingKey } });
const trainer = new TrainingApi.TrainingAPIClient(credentials, trainingEndpoint);
const predictor_credentials = new msRest.ApiKeyCredentials({ inHeader: { "Prediction-key": predictionKey } });
const predictor = new PredictionApi.PredictionAPIClient(predictor_credentials, predictionEndpoint);

Добавление вспомогательных функций

Добавьте следующую функцию, c помощью которой можно будет выполнить несколько асинхронных вызовов. Вы используете ее позже.

const credentials = new msRest.ApiKeyCredentials({ inHeader: { "Training-key": trainingKey } });
const trainer = new TrainingApi.TrainingAPIClient(credentials, trainingEndpoint);
const predictor_credentials = new msRest.ApiKeyCredentials({ inHeader: { "Prediction-key": predictionKey } });
const predictor = new PredictionApi.PredictionAPIClient(predictor_credentials, predictionEndpoint);

Создание проекта службы "Пользовательское визуальное распознавание"

Запустите новую функцию, чтобы она содержала все вызовы функций службы "Пользовательское визуальное распознавание". Добавьте следующий код, чтобы создать проект Пользовательской службы визуального распознавания.

(async () => {
    console.log("Creating project...");
    const domains = await trainer.getDomains()
    const objDetectDomain = domains.find(domain => domain.type === "ObjectDetection");
    const sampleProject = await trainer.createProject("Sample Obj Detection Project", { domainId: objDetectDomain.id });

Добавление тегов в проект

Чтобы создать теги классификации в проекте, добавьте в функцию следующий код:

const forkTag = await trainer.createTag(sampleProject.id, "Fork");
const scissorsTag = await trainer.createTag(sampleProject.id, "Scissors");

Отправка и снабжение тегами изображений

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

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

const sampleDataRoot = "Images";

const forkImageRegions = {
    "fork_1.jpg": [0.145833328, 0.3509314, 0.5894608, 0.238562092],
    "fork_2.jpg": [0.294117659, 0.216944471, 0.534313738, 0.5980392],
    "fork_3.jpg": [0.09191177, 0.0682516545, 0.757352948, 0.6143791],
    "fork_4.jpg": [0.254901975, 0.185898721, 0.5232843, 0.594771266],
    "fork_5.jpg": [0.2365196, 0.128709182, 0.5845588, 0.71405226],
    "fork_6.jpg": [0.115196079, 0.133611143, 0.676470637, 0.6993464],
    "fork_7.jpg": [0.164215669, 0.31008172, 0.767156839, 0.410130739],
    "fork_8.jpg": [0.118872553, 0.318251669, 0.817401946, 0.225490168],
    "fork_9.jpg": [0.18259804, 0.2136765, 0.6335784, 0.643790841],
    "fork_10.jpg": [0.05269608, 0.282303959, 0.8088235, 0.452614367],
    "fork_11.jpg": [0.05759804, 0.0894935, 0.9007353, 0.3251634],
    "fork_12.jpg": [0.3345588, 0.07315363, 0.375, 0.9150327],
    "fork_13.jpg": [0.269607842, 0.194068655, 0.4093137, 0.6732026],
    "fork_14.jpg": [0.143382356, 0.218578458, 0.7977941, 0.295751631],
    "fork_15.jpg": [0.19240196, 0.0633497, 0.5710784, 0.8398692],
    "fork_16.jpg": [0.140931368, 0.480016381, 0.6838235, 0.240196079],
    "fork_17.jpg": [0.305147052, 0.2512582, 0.4791667, 0.5408496],
    "fork_18.jpg": [0.234068632, 0.445702642, 0.6127451, 0.344771236],
    "fork_19.jpg": [0.219362751, 0.141781077, 0.5919118, 0.6683006],
    "fork_20.jpg": [0.180147052, 0.239820287, 0.6887255, 0.235294119]
};

const scissorsImageRegions = {
    "scissors_1.jpg": [0.4007353, 0.194068655, 0.259803921, 0.6617647],
    "scissors_2.jpg": [0.426470578, 0.185898721, 0.172794119, 0.5539216],
    "scissors_3.jpg": [0.289215684, 0.259428144, 0.403186262, 0.421568632],
    "scissors_4.jpg": [0.343137264, 0.105833367, 0.332107842, 0.8055556],
    "scissors_5.jpg": [0.3125, 0.09766343, 0.435049027, 0.71405226],
    "scissors_6.jpg": [0.379901975, 0.24308826, 0.32107842, 0.5718954],
    "scissors_7.jpg": [0.341911763, 0.20714055, 0.3137255, 0.6356209],
    "scissors_8.jpg": [0.231617644, 0.08459154, 0.504901946, 0.8480392],
    "scissors_9.jpg": [0.170343131, 0.332957536, 0.767156839, 0.403594762],
    "scissors_10.jpg": [0.204656869, 0.120539248, 0.5245098, 0.743464053],
    "scissors_11.jpg": [0.05514706, 0.159754932, 0.799019635, 0.730392158],
    "scissors_12.jpg": [0.265931368, 0.169558853, 0.5061275, 0.606209159],
    "scissors_13.jpg": [0.241421565, 0.184264734, 0.448529422, 0.6830065],
    "scissors_14.jpg": [0.05759804, 0.05027781, 0.75, 0.882352948],
    "scissors_15.jpg": [0.191176474, 0.169558853, 0.6936275, 0.6748366],
    "scissors_16.jpg": [0.1004902, 0.279036, 0.6911765, 0.477124184],
    "scissors_17.jpg": [0.2720588, 0.131977156, 0.4987745, 0.6911765],
    "scissors_18.jpg": [0.180147052, 0.112369314, 0.6262255, 0.6666667],
    "scissors_19.jpg": [0.333333343, 0.0274019931, 0.443627447, 0.852941155],
    "scissors_20.jpg": [0.158088237, 0.04047389, 0.6691176, 0.843137264]
};

console.log("Adding images...");
let fileUploadPromises = [];

const forkDir = `${sampleDataRoot}/fork`;
const forkFiles = fs.readdirSync(forkDir);

await asyncForEach(forkFiles, async (file) => {
    const region = { tagId: forkTag.id, left: forkImageRegions[file][0], top: forkImageRegions[file][1], width: forkImageRegions[file][2], height: forkImageRegions[file][3] };
    const entry = { name: file, contents: fs.readFileSync(`${forkDir}/${file}`), regions: [region] };
    const batch = { images: [entry] };
    // Wait one second to accommodate rate limit.
    await setTimeoutPromise(1000, null);
    fileUploadPromises.push(trainer.createImagesFromFiles(sampleProject.id, batch));
});

const scissorsDir = `${sampleDataRoot}/scissors`;
const scissorsFiles = fs.readdirSync(scissorsDir);

await asyncForEach(scissorsFiles, async (file) => {
    const region = { tagId: scissorsTag.id, left: scissorsImageRegions[file][0], top: scissorsImageRegions[file][1], width: scissorsImageRegions[file][2], height: scissorsImageRegions[file][3] };
    const entry = { name: file, contents: fs.readFileSync(`${scissorsDir}/${file}`), regions: [region] };
    const batch = { images: [entry] };
    // Wait one second to accommodate rate limit.
    await setTimeoutPromise(1000, null);
    fileUploadPromises.push(trainer.createImagesFromFiles(sampleProject.id, batch));
});

await Promise.all(fileUploadPromises);

Важно!

Вам потребуется изменить путь к изображениям (sampleDataRootна основе того, где вы скачали репозиторий sdk для Python служб ИИ Azure).

Примечание.

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

Обучение проекта

Этот код создает первую итерацию модели прогнозирования.

console.log("Training...");
let trainingIteration = await trainer.trainProject(sampleProject.id);

// Wait for training to complete
console.log("Training started...");
while (trainingIteration.status == "Training") {
    console.log("Training status: " + trainingIteration.status);
    // wait for ten seconds
    await setTimeoutPromise(10000, null);
    trainingIteration = await trainer.getIteration(sampleProject.id, trainingIteration.id)
}
console.log("Training status: " + trainingIteration.status);

Публикация текущей итерации

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

// Publish the iteration to the end point
await trainer.publishIteration(sampleProject.id, trainingIteration.id, publishIterationName, predictionResourceId);    

Тестирование конечной точки прогнозирования

Чтобы отправить изображение в конечную точку прогнозирования и получить результат прогнозирования, добавьте в функцию указанный ниже код.

const testFile = fs.readFileSync(`${sampleDataRoot}/test/test_image.jpg`);
const results = await predictor.detectImage(sampleProject.id, publishIterationName, testFile)

// Show results
console.log("Results:");
results.predictions.forEach(predictedResult => {
    console.log(`\t ${predictedResult.tagName}: ${(predictedResult.probability * 100.0).toFixed(2)}% ${predictedResult.boundingBox.left},${predictedResult.boundingBox.top},${predictedResult.boundingBox.width},${predictedResult.boundingBox.height}`);
});

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

})()

Выполнение приложения

Запустите приложение, выполнив команду node для файла quickstart.

node index.js

Выходные данные приложения должны появиться в консоли. Вы можете убедиться, что тестовое изображение (в <sampleDataRoot>/Test/) помечено соответствующим образом и область обнаружения верна. Вы также можете вернуться к веб-сайту Пользовательской службы визуального распознавания и просмотреть текущее состояние созданного проекта.

Очистка ресурсов

Если нужно реализовать собственный проект распознавания объектов (или использовать вместо него проект классификации изображений), вы можете удалить проект распознавания вилок и ножниц из этого примера. При работе в бесплатной подписке на Пользовательское визуальное распознавание можно создать два проекта.

На веб-сайте Пользовательской службы визуального распознавания перейдите в раздел проектов и щелкните значок корзины под заголовком "My New Project" (Мой новый проект).

Screenshot of a panel labeled My New Project with a trash can icon.

Следующие шаги

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

Начало работы с клиентской библиотекой службы "Пользовательское визуальное распознавание" для Python. Выполните приведенные здесь действия, чтобы установить пакет и протестировать пример кода для сборки модели обнаружения объектов. Здесь объясняется, как создать проект, добавить теги, обучить проект и использовать URL-адрес конечной точки прогнозирования проекта для программного тестирования. Этот пример можно использовать как шаблон при создании собственного приложения для распознавания изображений.

Примечание.

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

Используйте клиентскую библиотеку службы "Пользовательское визуальное распознавание" для Python, чтобы выполнять такие действия:

  • Создание проекта службы "Пользовательское визуальное распознавание"
  • Добавление тегов в проект
  • Отправка и снабжение тегами изображений
  • Обучение проекта
  • Публикация текущей итерации
  • Тестирование конечной точки прогнозирования

Справочная документация | Исходный код библиотеки | Пакет (PyPI) | Примеры

Необходимые компоненты

  • Подписка Azure — создайте бесплатную учетную запись.
  • Python 3.x
    • Установка Python должна включать pip. Чтобы проверить, установлен ли pip, выполните команду pip --version в командной строке. Чтобы использовать pip, установите последнюю версию Python.
  • После получения подписки Azure создайте ресурс Пользовательское визуальное распознавание в портал Azure для создания учебного и прогнозирующего ресурса.
    • Используйте бесплатную ценовую категорию (F0), чтобы опробовать службу, а затем выполните обновление до платного уровня для рабочей среды.

Создание переменной среды

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

Переход на портал Azure. Если Пользовательское визуальное распознавание ресурсы, созданные в разделе предварительных требований, развернуты успешно, нажмите кнопку "Перейти к ресурсу" в разделе "Дальнейшие действия". Ключи и конечные точки можно найти на страницах ключей и конечных точек ресурсов в разделе управления ресурсами. Вам потребуется получить ключи для ресурсов обучения и прогнозирования, а также конечных точек API.

Идентификатор ресурса прогнозирования можно найти на вкладке "Свойства" ресурса прогнозирования в портал Azure, указанном в качестве идентификатора ресурса.

Совет

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

Внимание

Не включайте ключ непосредственно в код и никогда не публикуйте его. Дополнительные варианты проверки подлинности, такие как Azure Key Vault, см. в статье по безопасности служб ИИ Azure.

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

  1. Чтобы задать VISION_TRAINING KEY переменную среды, замените your-training-key одним из ключей для учебного ресурса.
  2. Чтобы задать переменную среды, замените your-training-endpoint конечной VISION_TRAINING_ENDPOINT точкой для ресурса обучения.
  3. Чтобы задать VISION_PREDICTION_KEY переменную среды, замените your-prediction-key одним из ключей для ресурса прогнозирования.
  4. Чтобы задать переменную среды, замените your-prediction-endpoint конечной VISION_PREDICTION_ENDPOINT точкой для ресурса прогнозирования.
  5. Чтобы задать VISION_PREDICTION_RESOURCE_ID переменную среды, замените your-resource-id идентификатор ресурса для ресурса прогнозирования.
setx VISION_TRAINING_KEY your-training-key
setx VISION_TRAINING_ENDPOINT your-training-endpoint
setx VISION_PREDICTION_KEY your-prediction-key
setx VISION_PREDICTION_ENDPOINT your-prediction-endpoint
setx VISION_PREDICTION_RESOURCE_ID your-resource-id

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

Установка

Установка клиентской библиотеки

Чтобы написать приложение для анализа изображений с помощью службы "Пользовательское визуальное распознавание" для Python, вам потребуется клиентская библиотека этой службы. После установки Python выполните следующую команду в PowerShell или в окне консоли:

pip install azure-cognitiveservices-vision-customvision

Создание приложения Python

Создайте файл Python и импортируйте следующие библиотеки.

from azure.cognitiveservices.vision.customvision.training import CustomVisionTrainingClient
from azure.cognitiveservices.vision.customvision.prediction import CustomVisionPredictionClient
from azure.cognitiveservices.vision.customvision.training.models import ImageFileCreateBatch, ImageFileCreateEntry, Region
from msrest.authentication import ApiKeyCredentials
import os, time, uuid

Совет

Хотите просмотреть готовый файл с кодом для этого краткого руководства? Его можно найти на сайте GitHub, где размещены примеры кода для этого краткого руководства.

Создайте переменные для конечной точки Azure и ключей ресурса.

# Replace with valid values
ENDPOINT = os.environ["VISION_TRAINING_ENDPOINT"]
training_key = os.environ["VISION_TRAINING_KEY"]
prediction_key = os.environ["VISION_PREDICTION_KEY"]
prediction_resource_id = os.environ["VISION_PREDICTION_RESOURCE_ID"]

Объектная модель

Имя Описание
CustomVisionTrainingClient Этот класс обрабатывает создание, обучение и публикацию ваших моделей.
CustomVisionPredictionClient Этот класс обрабатывает запросы ваших моделей для прогнозов обнаружения объектов.
ImagePrediction Этот класс определяет прогнозирование одного объекта на одном изображении. Он содержит свойства для идентификатора объекта и его имени, расположение ограничивающего прямоугольника объекта и оценку достоверности.

Примеры кода

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

аутентификация клиента;

Создайте экземпляр клиента для обучения и прогноза, используя ключи и конечную точку. Создайте объекты ApiKeyServiceClientCredentials со своими ключами и используйте их с конечной точкой для создания объекта CustomVisionTrainingClient и CustomVisionPredictionClient.

credentials = ApiKeyCredentials(in_headers={"Training-key": training_key})
trainer = CustomVisionTrainingClient(ENDPOINT, credentials)
prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})
predictor = CustomVisionPredictionClient(ENDPOINT, prediction_credentials)

Создание проекта службы "Пользовательское визуальное распознавание"

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

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

publish_iteration_name = "detectModel"

# Find the object detection domain
obj_detection_domain = next(domain for domain in trainer.get_domains() if domain.type == "ObjectDetection" and domain.name == "General")

# Create a new project
print ("Creating project...")
# Use uuid to avoid project name collisions.
project = trainer.create_project(str(uuid.uuid4()), domain_id=obj_detection_domain.id)

Добавление тегов в проект

Чтобы создать теги объекта в проекте, добавьте следующий код:

# Make two tags in the new project
fork_tag = trainer.create_tag(project.id, "fork")
scissors_tag = trainer.create_tag(project.id, "scissors")

Отправка и снабжение тегами изображений

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

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

fork_image_regions = {
    "fork_1": [ 0.145833328, 0.3509314, 0.5894608, 0.238562092 ],
    "fork_2": [ 0.294117659, 0.216944471, 0.534313738, 0.5980392 ],
    "fork_3": [ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 ],
    "fork_4": [ 0.254901975, 0.185898721, 0.5232843, 0.594771266 ],
    "fork_5": [ 0.2365196, 0.128709182, 0.5845588, 0.71405226 ],
    "fork_6": [ 0.115196079, 0.133611143, 0.676470637, 0.6993464 ],
    "fork_7": [ 0.164215669, 0.31008172, 0.767156839, 0.410130739 ],
    "fork_8": [ 0.118872553, 0.318251669, 0.817401946, 0.225490168 ],
    "fork_9": [ 0.18259804, 0.2136765, 0.6335784, 0.643790841 ],
    "fork_10": [ 0.05269608, 0.282303959, 0.8088235, 0.452614367 ],
    "fork_11": [ 0.05759804, 0.0894935, 0.9007353, 0.3251634 ],
    "fork_12": [ 0.3345588, 0.07315363, 0.375, 0.9150327 ],
    "fork_13": [ 0.269607842, 0.194068655, 0.4093137, 0.6732026 ],
    "fork_14": [ 0.143382356, 0.218578458, 0.7977941, 0.295751631 ],
    "fork_15": [ 0.19240196, 0.0633497, 0.5710784, 0.8398692 ],
    "fork_16": [ 0.140931368, 0.480016381, 0.6838235, 0.240196079 ],
    "fork_17": [ 0.305147052, 0.2512582, 0.4791667, 0.5408496 ],
    "fork_18": [ 0.234068632, 0.445702642, 0.6127451, 0.344771236 ],
    "fork_19": [ 0.219362751, 0.141781077, 0.5919118, 0.6683006 ],
    "fork_20": [ 0.180147052, 0.239820287, 0.6887255, 0.235294119 ]
}

scissors_image_regions = {
    "scissors_1": [ 0.4007353, 0.194068655, 0.259803921, 0.6617647 ],
    "scissors_2": [ 0.426470578, 0.185898721, 0.172794119, 0.5539216 ],
    "scissors_3": [ 0.289215684, 0.259428144, 0.403186262, 0.421568632 ],
    "scissors_4": [ 0.343137264, 0.105833367, 0.332107842, 0.8055556 ],
    "scissors_5": [ 0.3125, 0.09766343, 0.435049027, 0.71405226 ],
    "scissors_6": [ 0.379901975, 0.24308826, 0.32107842, 0.5718954 ],
    "scissors_7": [ 0.341911763, 0.20714055, 0.3137255, 0.6356209 ],
    "scissors_8": [ 0.231617644, 0.08459154, 0.504901946, 0.8480392 ],
    "scissors_9": [ 0.170343131, 0.332957536, 0.767156839, 0.403594762 ],
    "scissors_10": [ 0.204656869, 0.120539248, 0.5245098, 0.743464053 ],
    "scissors_11": [ 0.05514706, 0.159754932, 0.799019635, 0.730392158 ],
    "scissors_12": [ 0.265931368, 0.169558853, 0.5061275, 0.606209159 ],
    "scissors_13": [ 0.241421565, 0.184264734, 0.448529422, 0.6830065 ],
    "scissors_14": [ 0.05759804, 0.05027781, 0.75, 0.882352948 ],
    "scissors_15": [ 0.191176474, 0.169558853, 0.6936275, 0.6748366 ],
    "scissors_16": [ 0.1004902, 0.279036, 0.6911765, 0.477124184 ],
    "scissors_17": [ 0.2720588, 0.131977156, 0.4987745, 0.6911765 ],
    "scissors_18": [ 0.180147052, 0.112369314, 0.6262255, 0.6666667 ],
    "scissors_19": [ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 ],
    "scissors_20": [ 0.158088237, 0.04047389, 0.6691176, 0.843137264 ]
}

Примечание.

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

Затем используйте карту ассоциаций, чтобы передать каждый пример изображения с его координатами региона (можно передать до 64 изображений в одном пакете). Добавьте следующий код.

base_image_location = os.path.join (os.path.dirname(__file__), "Images")

# Go through the data table above and create the images
print ("Adding images...")
tagged_images_with_regions = []

for file_name in fork_image_regions.keys():
    x,y,w,h = fork_image_regions[file_name]
    regions = [ Region(tag_id=fork_tag.id, left=x,top=y,width=w,height=h) ]

    with open(os.path.join (base_image_location, "fork", file_name + ".jpg"), mode="rb") as image_contents:
        tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))

for file_name in scissors_image_regions.keys():
    x,y,w,h = scissors_image_regions[file_name]
    regions = [ Region(tag_id=scissors_tag.id, left=x,top=y,width=w,height=h) ]

    with open(os.path.join (base_image_location, "scissors", file_name + ".jpg"), mode="rb") as image_contents:
        tagged_images_with_regions.append(ImageFileCreateEntry(name=file_name, contents=image_contents.read(), regions=regions))

upload_result = trainer.create_images_from_files(project.id, ImageFileCreateBatch(images=tagged_images_with_regions))
if not upload_result.is_batch_successful:
    print("Image batch upload failed.")
    for image in upload_result.images:
        print("Image status: ", image.status)
    exit(-1)

Примечание.

Вам потребуется изменить путь к изображениям на основе того, где вы скачали репозиторий sdk для Python служб ИИ Azure ранее.

Обучение проекта

Этот код создает первую итерацию модели прогнозирования.

print ("Training...")
iteration = trainer.train_project(project.id)
while (iteration.status != "Completed"):
    iteration = trainer.get_iteration(project.id, iteration.id)
    print ("Training status: " + iteration.status)
    time.sleep(1)

Совет

Обучение с использованием выбранных тегов

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

Публикация текущей итерации

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

# The iteration is now trained. Publish it to the project endpoint
trainer.publish_iteration(project.id, iteration.id, publish_iteration_name, prediction_resource_id)
print ("Done!")

Тестирование конечной точки прогнозирования

Чтобы отправить изображение в конечную точку прогнозирования и извлечь прогнозирование, добавьте в конец файла следующий код:

# Now there is a trained endpoint that can be used to make a prediction

# Open the sample image and get back the prediction results.
with open(os.path.join (base_image_location, "test", "test_image.jpg"), mode="rb") as test_data:
    results = predictor.detect_image(project.id, publish_iteration_name, test_data)

# Display the results.    
for prediction in results.predictions:
    print("\t" + prediction.tag_name + ": {0:.2f}% bbox.left = {1:.2f}, bbox.top = {2:.2f}, bbox.width = {3:.2f}, bbox.height = {4:.2f}".format(prediction.probability * 100, prediction.bounding_box.left, prediction.bounding_box.top, prediction.bounding_box.width, prediction.bounding_box.height))

Выполнение приложения

Запустите CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

Выходные данные приложения должны появиться в консоли. Вы можете убедиться, что тестовое изображение (в папке <base_image_location>/images/Test) помечено соответствующим образом и что область обнаружения указана правильно. Вы также можете вернуться к веб-сайту Пользовательской службы визуального распознавания и просмотреть текущее состояние созданного проекта.

Очистка ресурсов

Если нужно реализовать собственный проект распознавания объектов (или использовать вместо него проект классификации изображений), вы можете удалить проект распознавания вилок и ножниц из этого примера. При работе в бесплатной подписке на Пользовательское визуальное распознавание можно создать два проекта.

На веб-сайте Пользовательской службы визуального распознавания перейдите в раздел проектов и щелкните значок корзины под заголовком "My New Project" (Мой новый проект).

Screenshot of a panel labeled My New Project with a trash can icon.

Следующие шаги

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