Partager via


Démarrage rapide : Créer un projet de détection d’objets avec la bibliothèque de client Custom Vision

Bien démarrer avec la bibliothèque de client Custom Vision pour .NET Suivez les étapes ci-après pour installer le package et essayer l’exemple de code visant à créer un modèle de détection d’objets. Vous allez créer un projet, ajouter des étiquettes, entraîner le projet sur des exemples d’images et utiliser l’URL de point de terminaison de prédiction du projet pour le tester programmatiquement. Utilisez cet exemple comme modèle pour générer votre propre application de reconnaissance d’image.

Notes

Si vous souhaitez créer et entraîner un modèle de détection d’objets sans écrire de code, consultez à la place les instructions basées sur le navigateur.

Documentation de référence | Code source de la bibliothèque (entraînement) (prédiction) | Package (NuGet) (entraînement) (prédiction) | Exemples

Prérequis

Créer des variables d’environnement

Dans cet exemple, vous allez écrire vos informations d’identification dans des variables d’environnement sur l’ordinateur local exécutant l’application.

Accédez au portail Azure. Si les ressources Custom Vision que vous avez créées dans la section Prérequis ont été déployées correctement, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous pouvez trouver vos clés et vos point de terminaison dans les pages Clés et point de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés pour vos ressources d’entraînement et de prédiction, ainsi que les points de terminaison d’API.

L’ID de ressource de prévision est disponible dans le portail Microsoft Azure, sous l’onglet Propriétés de la ressource, listé comme ID de ressource.

Conseil

Vous utilisez également https://www.customvision.ai pour obtenir ces valeurs. Après vous être connecté, sélectionnez l’icône Paramètres en haut à droite. Dans les pages de Paramètres, vous pouvez visualiser l’ensemble des clés, ID de ressource et points de terminaison.

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions relatives à votre système d’exploitation et à votre environnement de développement.

  • Pour définir la variable d’environnement VISION_TRAINING KEY, remplacez <your-training-key> par l’une des clés de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT, remplacez <your-training-endpoint> par le point de terminaison de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_PREDICTION_KEY, remplacez <your-prediction-key> par l’une des clés de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT, remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID, remplacez <your-resource-id> par l’ID de votre ressource de prévision.

Important

Si vous utilisez une clé API, stockez-la en toute sécurité dans un autre emplacement, par exemple dans Azure Key Vault. N'incluez pas la clé API directement dans votre code et ne la diffusez jamais publiquement.

Pour plus d’informations sur la sécurité des services IA, consultez Authentifier les demandes auprès d’Azure AI services.

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>

Une fois que vous avez ajouté les variables d’environnement, il peut être nécessaire de redémarrer tous les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de la console.

Configuration

Créer une application C#

À l’aide de Visual Studio, créez une application .NET Core.

Installer la bibliothèque de client

Une fois que vous avez créé un projet, installez la bibliothèque de client en cliquant avec le bouton droit sur la solution de projet dans l’Explorateur de solutions et en sélectionnant Gérer les packages NuGet. Dans le gestionnaire de package qui s’ouvre, sélectionnez Parcourir, cochez Inclure la préversion et recherchez Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training et Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Sélectionnez la version la plus récente, puis Installer.

Conseil

Vous voulez voir l’intégralité du fichier de code de démarrage rapide à la fois ? Vous le trouverez sur GitHub, qui contient les exemples de code utilisés dans ce guide de démarrage rapide.

À partir du répertoire du projet, ouvrez le fichier program.cs et ajoutez ce qui suit en utilisant les directives using suivantes :

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;

Dans la méthode Principal de l’application, créez des variables récupérant les clés et les points de terminaison de votre ressource à partir de variables d’environnement. Vous allez également déclarer des objets de base à utiliser ultérieurement.

    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";

Dans la méthode Main de l’application, ajoutez des appels pour les méthodes utilisées dans ce guide de démarrage rapide. Vous les implémenterez ultérieurement.

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);

Authentifier le client

Dans une nouvelle méthode, instanciez les clients d’entraînement et de prédiction à l’aide de votre point de terminaison et de vos clés.

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;
}

Créer un projet de service Custom Vision

La méthode suivante crée un projet de détection d’objet. Le projet créé apparaît sur le site web Custom Vision. Consultez la méthode CreateProject pour spécifier d’autres options quand vous créez votre projet (procédure expliquée dans le guide du portail web Build a detector [Créer un détecteur]).

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;
}

Ajouter des balises au projet

Cette méthode définit les étiquettes sur lesquelles vous allez effectuer l’entraînement du modèle.

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");
}

Charger et étiqueter des images

Tout d’abord, téléchargez les exemples d’images pour ce projet. Enregistrez le contenu du dossier des exemples d’images sur votre appareil local.

Lorsque vous appliquez des balises à des images dans des projets de détection d’objet, vous devez préciser la région de chaque objet balisé avec des coordonnées normalisées. Le code suivant associe chaque exemple d’image à sa région balisée.

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 } }
    };

Notes

Pour vos propres projets, si vous n’avez pas d’utilitaire permettant d’effectuer des opérations de glisser-déposer pour marquer les coordonnées des régions, vous pouvez utiliser l’IU web sur le site web Custom Vision. Dans cet exemple, les coordonnées sont déjà fournies.

Cette carte d’associations est alors utilisée pour charger chaque exemple d’image avec ses coordonnées de région. Vous pouvez charger jusqu’à 64 images dans un même lot. Vous devrez peut-être changer la valeur de imagePath pour qu’elle pointe vers les emplacements de dossier appropriés.

    // 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));
}

À ce stade, vous avez chargé tous les exemples d’images et vous avez étiqueté chacune d’elles (fourchette ou ciseaux) avec un rectangle de pixels associé.

Entraîner le projet

Cette méthode crée la première itération d’entraînement dans le projet. Elle interroge le service jusqu’à la fin de l’entraînement.

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);
    }
}

Conseil

Entraîner avec des étiquettes sélectionnées

Vous pouvez, si vous le souhaitez, effectuer l’entraînement sur un sous-ensemble de vos étiquettes appliquées. Vous pouvez procéder de la sorte si vous n’avez pas encore suffisamment appliqué certaines étiquettes, contrairement à d’autres. Dans l’appel TrainProject, utilisez le paramètre trainingParameters. Construisez un TrainingParameters et définissez sa propriété SelectedTags sur une liste d’ID des étiquettes que vous souhaitez utiliser. Le modèle effectue l’entraînement pour ne reconnaître que les étiquettes présentes dans cette liste.

Publier l’itération actuelle

Cette méthode rend l’itération actuelle du modèle disponible pour l’interrogation. Vous pouvez utiliser le nom du modèle comme référence pour envoyer des demandes de prédiction. Vous devez entrer votre propre valeur pour predictionResourceId. L’ID de ressource de prédiction est disponible sous l’onglet Propriétés de la ressource dans le portail Azure, listé comme ID de ressource.

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");
}

Tester le point de terminaison de prédiction

Cette méthode charge l’image test, interroge le point de terminaison du modèle et renvoie des données de prédiction à la console.

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();
}

Exécution de l'application

Exécutez l’application en cliquant sur le bouton Déboguer en haut de la fenêtre de l’IDE.

Lors de l’exécution de l’application, une fenêtre de console s’ouvre et la sortie suivante est écrite :

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 ]

Vous pouvez alors vérifier que l’image test (trouvée dans Images/Test/) est balisée de façon appropriée et que la région de détection est correcte. À ce stade, vous pouvez appuyer sur n’importe quelle touche pour quitter l’application.

Nettoyer les ressources

Si vous voulez implémenter votre projet de détection d’objets (ou essayer un projet de classification d’images), supprimez le projet de détection de fourchettes/ciseaux de cet exemple. Avec un abonnement gratuit, vous pouvez avoir deux projets Custom Vision.

Sur le site web Custom Vision, accédez à Projects (Projets) puis sélectionnez la corbeille sous My New Project (Nouveau projet).

Capture d’écran d’un panneau étiqueté Mon Nouveau Projet avec une icône de corbeille.

Étapes suivantes

Vous avez à présent effectué chaque étape du processus de détection d’objet dans le code. Cet exemple exécute une seule itération d’entraînement, mais vous aurez souvent besoin d’entraîner et de tester votre modèle à plusieurs reprises pour le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont identiques à la détection d’objet.

Ce guide fournit des instructions et un exemple de code pour vous aider à commencer à utiliser la bibliothèque de client Custom Vision pour Go afin de générer un modèle de détection d’objets. Vous allez créer un projet, ajouter des étiquettes, entraîner le projet et utiliser l’URL de point de terminaison de prédiction du projet pour le tester programmatiquement. Utilisez cet exemple comme modèle pour générer votre propre application de reconnaissance d’image.

Notes

Si vous souhaitez créer et entraîner un modèle de détection d’objets sans écrire de code, consultez à la place les instructions basées sur le navigateur.

La bibliothèque de client Custom Vision pour Go vous permet d’effectuer les tâches suivantes :

  • Créer un projet de service Custom Vision
  • Ajouter des balises au projet
  • Charger et étiqueter des images
  • Entraîner le projet
  • Publier l’itération actuelle
  • Tester le point de terminaison de prédiction

Documentation de référence (entraînement) (prédiction)

Prérequis

Créer des variables d’environnement

Dans cet exemple, vous allez écrire vos informations d’identification dans des variables d’environnement sur l’ordinateur local exécutant l’application.

Accédez au portail Azure. Si les ressources Custom Vision que vous avez créées dans la section Prérequis ont été déployées correctement, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous pouvez trouver vos clés et vos point de terminaison dans les pages Clés et point de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés pour vos ressources d’entraînement et de prédiction, ainsi que les points de terminaison d’API.

L’ID de ressource de prévision est disponible dans le portail Microsoft Azure, sous l’onglet Propriétés de la ressource, listé comme ID de ressource.

Conseil

Vous utilisez également https://www.customvision.ai pour obtenir ces valeurs. Après vous être connecté, sélectionnez l’icône Paramètres en haut à droite. Dans les pages de Paramètres, vous pouvez visualiser l’ensemble des clés, ID de ressource et points de terminaison.

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions relatives à votre système d’exploitation et à votre environnement de développement.

  • Pour définir la variable d’environnement VISION_TRAINING KEY, remplacez <your-training-key> par l’une des clés de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT, remplacez <your-training-endpoint> par le point de terminaison de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_PREDICTION_KEY, remplacez <your-prediction-key> par l’une des clés de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT, remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID, remplacez <your-resource-id> par l’ID de votre ressource de prévision.

Important

Si vous utilisez une clé API, stockez-la en toute sécurité dans un autre emplacement, par exemple dans Azure Key Vault. N'incluez pas la clé API directement dans votre code et ne la diffusez jamais publiquement.

Pour plus d’informations sur la sécurité des services IA, consultez Authentifier les demandes auprès d’Azure AI services.

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>

Une fois que vous avez ajouté les variables d’environnement, il peut être nécessaire de redémarrer tous les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de la console.

Configuration

Installer la bibliothèque de client Custom Vision

Pour écrire une application d’analyse d’image avec Custom Vision pour Go, vous avez besoin de la bibliothèque de client du service Custom Vision. Exécutez la commande suivante dans PowerShell :

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

Ou, si vous utilisez dep, au sein de votre dépôt, exécutez :

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

Obtenir l’exemple d’images

Cet exemple utilise les images du référentiel d’exemples du kit de développement logiciel (SDK) Python d’Azure AI services sur GitHub. Clonez ou téléchargez ce référentiel sur votre environnement de développement. Mémorisez l’emplacement du dossier pour une prochaine étape.

Créer le projet Custom Vision

Créez un fichier nommé sample.go dans le répertoire de projet de votre choix et ouvrez-le dans votre éditeur de code préféré.

Pour créer un nouveau projet Service Vision personnalisée, ajoutez le code suivant à votre script.

Consultez la méthode CreateProject pour spécifier d’autres options quand vous créez votre projet (procédure expliquée dans le guide du portail web Build a detector [Créer un détecteur]).

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, "")

Créer des balises dans un projet

Pour créer des balises de classification dans votre projet, ajoutez le code suivant à la fin du fichier 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))

Charger et étiqueter des images

Lorsque vous appliquez des balises à des images dans des projets de détection d’objet, vous devez préciser la région de chaque objet balisé avec des coordonnées normalisées.

Notes

Si vous n’avez pas d’utilitaire permettant d’effectuer des opérations de glisser-déposer pour marquer les coordonnées des régions, vous pouvez utiliser l’IU web sur Customvision.ai. Dans cet exemple, les coordonnées sont déjà fournies.

Pour ajouter les images, les régions et les balises au projet, insérez le code suivant après la création de la balise. Notez que dans ce tutoriel, les régions sont codées en dur. Les régions spécifient le niveau du bit dans des coordonnées normalisées, et ces dernières sont données dans l’ordre : gauche, haut, largeur et hauteur.

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 },
}

Utilisez alors cette carte d’associations pour charger chaque exemple d’image avec ses coordonnées de région (vous pouvez charger jusqu’à 64 images dans un même lot). Ajoutez le code ci-dessous.

Notes

Vous devez changer le chemin des images, selon l’emplacement où vous avez préalablement téléchargé l’exemple de projet du kit de développement logiciel (SDK) Go d’Azure AI services.

// 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.")
}     

Entraîner et publier le projet

Ce code crée la première itération du modèle de prédiction, puis publie cette itération sur le point de terminaison de prédiction. Le nom donné à l’itération publiée peut être utilisé pour envoyer des requêtes de prédiction. L’itération n’est pas disponible sur le point de terminaison de prédiction tant qu’elle n’est pas publiée.

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))

Utiliser le point de terminaison de prédiction

Pour envoyer une image au point de terminaison de prédiction et récupérer la prédiction, ajoutez le code suivant à la fin du fichier :

    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("")
    }
}

Exécution de l'application

Exécutez sample.go.

go run sample.go

La sortie de l’application doit apparaître dans la console. Vous pouvez alors vérifier que l’image test (trouvée dans samples/vision/images/Test) est balisée de façon appropriée et que la région de détection est correcte.

Nettoyer les ressources

Si vous voulez implémenter votre projet de détection d’objets (ou essayer un projet de classification d’images), supprimez le projet de détection de fourchettes/ciseaux de cet exemple. Avec un abonnement gratuit, vous pouvez avoir deux projets Custom Vision.

Sur le site web Custom Vision, accédez à Projects (Projets) puis sélectionnez la corbeille sous My New Project (Nouveau projet).

Capture d’écran d’un panneau étiqueté Mon Nouveau Projet avec une icône de corbeille.

Étapes suivantes

Vous avez à présent effectué chaque étape du processus de détection d’objet dans le code. Cet exemple exécute une seule itération d’entraînement, mais vous aurez souvent besoin d’entraîner et de tester votre modèle à plusieurs reprises pour le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont identiques à la détection d’objet.

Bien démarrer avec l’utilisation de la bibliothèque de client Custom Vision pour Java afin de générer un modèle de détection d’objet Suivez les étapes suivantes pour installer le package et essayer l’exemple de code pour les tâches de base. Utilisez cet exemple comme modèle pour générer votre propre application de reconnaissance d’image.

Notes

Si vous souhaitez créer et entraîner un modèle de détection d’objets sans écrire de code, consultez à la place les instructions basées sur le navigateur.

Utilisez la bibliothèque de client Custom Vision pour Java pour :

  • Créer un projet de service Custom Vision
  • Ajouter des balises au projet
  • Charger et étiqueter des images
  • Entraîner le projet
  • Publier l’itération actuelle
  • Tester le point de terminaison de prédiction

Documentation de référence | Code source de la bibliothèque (entraînement) (prédiction) | Artefact (Maven) (entraînement) (prédiction) | Exemples

Prérequis

Créer des variables d’environnement

Dans cet exemple, vous allez écrire vos informations d’identification dans des variables d’environnement sur l’ordinateur local exécutant l’application.

Accédez au portail Azure. Si les ressources Custom Vision que vous avez créées dans la section Prérequis ont été déployées correctement, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous pouvez trouver vos clés et vos point de terminaison dans les pages Clés et point de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés pour vos ressources d’entraînement et de prédiction, ainsi que les points de terminaison d’API.

L’ID de ressource de prévision est disponible dans le portail Microsoft Azure, sous l’onglet Propriétés de la ressource, listé comme ID de ressource.

Conseil

Vous utilisez également https://www.customvision.ai pour obtenir ces valeurs. Après vous être connecté, sélectionnez l’icône Paramètres en haut à droite. Dans les pages de Paramètres, vous pouvez visualiser l’ensemble des clés, ID de ressource et points de terminaison.

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions relatives à votre système d’exploitation et à votre environnement de développement.

  • Pour définir la variable d’environnement VISION_TRAINING KEY, remplacez <your-training-key> par l’une des clés de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT, remplacez <your-training-endpoint> par le point de terminaison de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_PREDICTION_KEY, remplacez <your-prediction-key> par l’une des clés de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT, remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID, remplacez <your-resource-id> par l’ID de votre ressource de prévision.

Important

Si vous utilisez une clé API, stockez-la en toute sécurité dans un autre emplacement, par exemple dans Azure Key Vault. N'incluez pas la clé API directement dans votre code et ne la diffusez jamais publiquement.

Pour plus d’informations sur la sécurité des services IA, consultez Authentifier les demandes auprès d’Azure AI services.

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>

Une fois que vous avez ajouté les variables d’environnement, il peut être nécessaire de redémarrer tous les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de la console.

Configuration

Créer un projet Gradle

Dans une fenêtre de console (telle que cmd, PowerShell ou bash), créez un répertoire pour votre application et accédez-y.

mkdir myapp && cd myapp

Exécutez la commande gradle init à partir de votre répertoire de travail. Cette commande crée des fichiers de build essentiels pour Gradle, notamment build.gradle.kts, qui est utilisé au moment de l’exécution pour créer et configurer votre application.

gradle init --type basic

Quand vous êtes invité à choisir un DSL, sélectionnez Kotlin.

Installer la bibliothèque de client

Recherchez build.gradle.kts et ouvrez-le avec votre IDE ou votre éditeur de texte habituel. Copiez-y ensuite la configuration de build suivante. Cette configuration définit le projet en tant qu’application Java dont le point d’entrée est la classe CustomVisionQuickstart. Elle importe les bibliothèques Custom Vision.

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")
}

Créer un fichier Java

Dans votre répertoire de travail, exécutez la commande suivante pour créer un dossier de projet source :

mkdir -p src/main/java

Accédez au nouveau dossier et créez le fichier CustomVisionQuickstart.java. Ouvrez-le dans votre éditeur ou IDE habituel et ajoutez les instructions import suivantes :

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;

Conseil

Vous voulez voir l’intégralité du fichier de code de démarrage rapide à la fois ? Vous le trouverez sur GitHub, qui contient les exemples de code utilisés dans ce guide de démarrage rapide.

Dans la classe CustomVisionQuickstart de l’application, créez des variables qui récupèrent les clés et les points de terminaison de votre ressource à partir de variables d’environnement.

// 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");

Dans la méthode main de l’application, ajoutez des appels pour les méthodes utilisées dans ce guide de démarrage rapide. Vous les définirez plus tard.

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

Modèle objet

Les classes et interfaces suivantes gèrent certaines des principales fonctionnalités de la bibliothèque de client Custom Vision pour Java.

Name Description
CustomVisionTrainingClient Cette classe gère la création, l’entraînement et la publication de vos modèles.
CustomVisionPredictionClient Cette classe gère l’interrogation de vos modèles pour les prédictions de détection d’objets.
ImagePrediction Cette classe définit une prédiction d’objet unique sur une seule image. Elle comprend des propriétés pour l’ID et le nom de l’objet, la position du rectangle englobant de l’objet et un score de confiance.

Exemples de code

Ces extraits de code vous montrent comment effectuer les tâches suivantes avec la bibliothèque de client Custom Vision pour Java :

Authentifier le client

Dans votre méthode main, instanciez les clients d’entraînement et de prédiction à l’aide de votre point de terminaison et de vos clés.

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

Créer un projet de service Custom Vision

La méthode suivante crée un projet de détection d’objet. Le projet créé apparaît sur le site web Custom Vision sur lequel vous êtes allé plus tôt. Consultez les surcharges de méthode CreateProject pour spécifier d’autres options quand vous créez votre projet (procédure expliquée dans le guide du portail web Build a detector [Créer un détecteur]).

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;
}

Ajouter des mots clés à votre projet

Cette méthode définit les étiquettes sur lesquelles vous allez effectuer l’entraînement du modèle.

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();
}

Charger et étiqueter des images

Tout d’abord, téléchargez les exemples d’images pour ce projet. Enregistrez le contenu du dossier des exemples d’images sur votre appareil local.

Notes

Vous avez besoin d’un jeu d’images plus étoffé pour mener à bien votre formation ? Trove, un projet Microsoft Garage, vous permet de collecter et d’acheter des ensembles d’images à des fins d’entraînement. Une fois que vous avez collecté vos images, vous pouvez les télécharger, puis les importer dans votre projet Custom Vision de la manière habituelle. Pour en savoir plus, consultez la page dédiée à Trove.

Lorsque vous appliquez des balises à des images dans des projets de détection d’objet, vous devez préciser la région de chaque objet balisé avec des coordonnées normalisées. Le code suivant associe chaque exemple d’image à sa région balisée.

Notes

Si vous n’avez pas d’utilitaire permettant d’effectuer des opérations de glisser-déposer pour marquer les coordonnées des régions, vous pouvez utiliser l’IU web sur Customvision.ai. Dans cet exemple, les coordonnées sont déjà fournies.

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 });

Le bloc de code suivant ajoute les images au projet. Vous devez changer les arguments des appels GetImage afin qu’ils pointent vers les emplacements des dossiers fork et scissors que vous avez téléchargés.

    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));
    }
}

L’extrait de code précédent utilise deux fonctions d’assistance qui récupèrent les images comme flux de ressources et les charge dans le service (vous pouvez charger jusqu’à 64 images dans un même lot). Définissez ces méthodes.

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;
}

Entraîner le projet

Cette méthode crée la première itération d’entraînement dans le projet. Elle interroge le service jusqu’à la fin de l’entraînement.

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());
}

Publier l’itération actuelle

Cette méthode rend l’itération actuelle du modèle disponible pour l’interrogation. Vous pouvez utiliser le nom du modèle comme référence pour envoyer des demandes de prédiction. Vous devez entrer votre propre valeur pour predictionResourceId. L’ID de ressource de prédiction est disponible sous l’onglet Propriétés de la ressource dans le portail Azure, listé comme ID de ressource.

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;
}

Tester le point de terminaison de prédiction

Cette méthode charge l’image test, interroge le point de terminaison du modèle et renvoie des données de prédiction à la console.

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()));
    }
}

Exécution de l'application

Vous pouvez générer l’application avec :

gradle build

Exécutez l’application avec la commande gradle run :

gradle run

Nettoyer les ressources

Si vous souhaitez nettoyer et supprimer un abonnement Azure AI services, vous pouvez supprimer la ressource ou le groupe de ressources. La suppression du groupe de ressources efface également les autres ressources qui y sont associées.

Si vous voulez implémenter votre projet de détection d’objets (ou essayer un projet de classification d’images), supprimez le projet de détection de fourchettes/ciseaux de cet exemple. Avec un abonnement gratuit, vous pouvez avoir deux projets Custom Vision.

Sur le site web Custom Vision, accédez à Projects (Projets) puis sélectionnez la corbeille sous My New Project (Nouveau projet).

Capture d’écran d’un panneau étiqueté Mon Nouveau Projet avec une icône de corbeille.

Étapes suivantes

Vous avez à présent effectué chaque étape du processus de détection d’objet dans le code. Cet exemple exécute une seule itération d’entraînement, mais vous aurez souvent besoin d’entraîner et de tester votre modèle à plusieurs reprises pour le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont identiques à la détection d’objet.

  • Qu’est-ce que Custom Vision ?
  • Le code source de cet exemple est disponible sur GitHub.

Ce guide fournit des instructions et un exemple de code pour vous aider à commencer à utiliser la bibliothèque de client Custom Vision pour Node.js afin de générer un modèle de détection d’objets. Vous allez créer un projet, ajouter des étiquettes, entraîner le projet et utiliser l’URL de point de terminaison de prédiction du projet pour le tester programmatiquement. Utilisez cet exemple comme modèle pour générer votre propre application de reconnaissance d’image.

Notes

Si vous souhaitez créer et entraîner un modèle de détection d’objets sans écrire de code, consultez à la place les instructions basées sur le navigateur.

Utilisez la bibliothèque de client Custom Vision pour .NET pour :

  • Créer un projet de service Custom Vision
  • Ajouter des balises au projet
  • Charger et étiqueter des images
  • Entraîner le projet
  • Publier l’itération actuelle
  • Tester le point de terminaison de prédiction

Documentation de référence (entraînement) (prédiction) | Package (npm) (entraînement) (prédiction) | Échantillons

Prérequis

  • Abonnement Azure - En créer un gratuitement
  • Version actuelle de Node.js
  • Une fois votre abonnement Azure obtenu, permet de créer une ressource Custom Vision dans le portail Microsoft Azure pour créer une ressource de formation et de prévision.
    • Vous pouvez utiliser le niveau tarifaire Gratuit (F0) pour tester le service, puis passer par la suite à un niveau payant pour la production.

Créer des variables d’environnement

Dans cet exemple, vous allez écrire vos informations d’identification dans des variables d’environnement sur l’ordinateur local exécutant l’application.

Accédez au portail Azure. Si les ressources Custom Vision que vous avez créées dans la section Prérequis ont été déployées correctement, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous pouvez trouver vos clés et vos point de terminaison dans les pages Clés et point de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés pour vos ressources d’entraînement et de prédiction, ainsi que les points de terminaison d’API.

L’ID de ressource de prévision est disponible dans le portail Microsoft Azure, sous l’onglet Propriétés de la ressource, listé comme ID de ressource.

Conseil

Vous utilisez également https://www.customvision.ai pour obtenir ces valeurs. Après vous être connecté, sélectionnez l’icône Paramètres en haut à droite. Dans les pages de Paramètres, vous pouvez visualiser l’ensemble des clés, ID de ressource et points de terminaison.

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions relatives à votre système d’exploitation et à votre environnement de développement.

  • Pour définir la variable d’environnement VISION_TRAINING KEY, remplacez <your-training-key> par l’une des clés de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT, remplacez <your-training-endpoint> par le point de terminaison de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_PREDICTION_KEY, remplacez <your-prediction-key> par l’une des clés de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT, remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID, remplacez <your-resource-id> par l’ID de votre ressource de prévision.

Important

Si vous utilisez une clé API, stockez-la en toute sécurité dans un autre emplacement, par exemple dans Azure Key Vault. N'incluez pas la clé API directement dans votre code et ne la diffusez jamais publiquement.

Pour plus d’informations sur la sécurité des services IA, consultez Authentifier les demandes auprès d’Azure AI services.

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>

Une fois que vous avez ajouté les variables d’environnement, il peut être nécessaire de redémarrer tous les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de la console.

Configuration

Création d’une application Node.js

Dans une fenêtre de console (telle que cmd, PowerShell ou bash), créez un répertoire pour votre application et accédez-y.

mkdir myapp && cd myapp

Exécutez la commande npm init pour créer une application de nœud avec un fichier package.json.

npm init

Installer la bibliothèque de client

Pour écrire une application d’analyse d’image avec Custom Vision pour Node.js, vous avez besoin des packages NPM Custom Vision. Pour les installer, exécutez la commande suivante dans PowerShell :

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

Le fichier package.json de votre application sera mis à jour avec les dépendances.

Créez un fichier nommé index.js et importez les bibliothèques suivantes :

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");

Conseil

Vous voulez voir l’intégralité du fichier de code de démarrage rapide à la fois ? Vous le trouverez sur GitHub, qui contient les exemples de code utilisés dans ce guide de démarrage rapide.

Créez des variables pour le point de terminaison et les clés Azure de votre ressource.

// 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"];

Ajoutez également des champs pour le nom de votre projet et un paramètre de délai d’attente pour les appels asynchrones.

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

Modèle objet

Nom Description
TrainingAPIClient Cette classe gère la création, l’entraînement et la publication de vos modèles.
PredictionAPIClient Cette classe gère l’interrogation de vos modèles pour les prédictions de détection d’objets.
Prédiction Cette interface définit une prédiction unique sur une seule image. Elle comprend des propriétés pour l’ID et le nom de l’objet ainsi qu’un score de confiance.

Exemples de code

Ces extraits de code vous montrent comment effectuer les tâches suivantes avec la bibliothèque de client Custom Vision pour JavaScript :

Authentifier le client

Instanciez les objets clients avec le point de terminaison et la clé. Créez un objet ApiKeyCredentials avec votre clé et utilisez-le avec votre point de terminaison pour créer un objet TrainingAPIClient et un objet 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);

Ajouter une fonction d’assistance

Ajoutez la fonction suivante pour faciliter la réalisation de plusieurs appels asynchrones. Vous l’utiliserez plus tard.

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);

Créer un projet de service Custom Vision

Démarrez une nouvelle fonction destinée à contenir tous vos appels de fonction Custom Vision. Ajoutez le code suivant pour créer un projet de service Custom Vision.

(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 });

Ajouter des balises au projet

Pour créer des étiquettes de classification dans votre projet, ajoutez le code suivant à votre fonction :

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

Charger et étiqueter des images

Tout d’abord, téléchargez les exemples d’images pour ce projet. Enregistrez le contenu du dossier des exemples d’images sur votre appareil local.

Pour ajouter les exemples d’images au projet, insérez le code suivant après la création de mots clés. Ce code charge chaque image avec la balise correspondante. Lorsque vous appliquez des balises à des images dans des projets de détection d’objet, vous devez préciser la région de chaque objet balisé avec des coordonnées normalisées. Pour ce tutoriel, les régions sont codées en dur inline avec le code. Les régions spécifient le niveau du bit dans des coordonnées normalisées, et ces dernières sont données dans l’ordre : gauche, haut, largeur et hauteur. Vous pouvez charger jusqu’à 64 images dans un même lot.

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);

Important

Vous devez changer le chemin des images (sampleDataRoot), selon l’emplacement où vous avez téléchargé le référentiel d’exemples du kit de développement logiciel (SDK) Python d’Azure AI services.

Notes

Si vous n’avez pas d’utilitaire permettant d’effectuer des opérations de glisser-déposer pour marquer les coordonnées des régions, vous pouvez utiliser l’IU web sur Customvision.ai. Dans cet exemple, les coordonnées sont déjà fournies.

Entraîner le projet

Ce code crée la première itération du modèle de prédiction.

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);

Publier l’itération actuelle

Ce code publie l’itération entraînée sur le point de terminaison de prédiction. Le nom donné à l’itération publiée peut être utilisé pour envoyer des requêtes de prédiction. Les itérations ne sont pas disponibles sur le point de terminaison de prédiction tant qu’elles n’ont pas été publiées.

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

Tester le point de terminaison de prédiction

Pour envoyer une image au point de terminaison de prédiction et récupérer la prédiction, ajoutez le code suivant à votre fonction.

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}`);
});

Ensuite, fermez votre fonction Custom Vision et appelez-la.

})()

Exécution de l'application

Exécutez l’application avec la commande node de votre fichier de démarrage rapide.

node index.js

La sortie de l’application doit apparaître dans la console. Vous pouvez alors vérifier que l’image de test (qui se trouve dans <sampleDataRoot>/Test/) est étiquetée de façon appropriée et que la région de détection est correcte. Vous pouvez aussi revenir sur le site web Custom Vision et consulter l’état actuel de votre nouveau projet.

Nettoyer les ressources

Si vous voulez implémenter votre projet de détection d’objets (ou essayer un projet de classification d’images), supprimez le projet de détection de fourchettes/ciseaux de cet exemple. Avec un abonnement gratuit, vous pouvez avoir deux projets Custom Vision.

Sur le site web Custom Vision, accédez à Projects (Projets) puis sélectionnez la corbeille sous My New Project (Nouveau projet).

Capture d’écran d’un panneau étiqueté Mon Nouveau Projet avec une icône de corbeille.

Étapes suivantes

Vous avez à présent effectué chaque étape du processus de détection d’objet dans le code. Cet exemple exécute une seule itération d’entraînement, mais vous aurez souvent besoin d’entraîner et de tester votre modèle à plusieurs reprises pour le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont identiques à la détection d’objet.

Bien démarrer avec la bibliothèque de client Custom Vision pour Python Suivez les étapes ci-après pour installer le package et essayer l’exemple de code visant à créer un modèle de détection d’objets. Vous allez créer un projet, ajouter des étiquettes, entraîner le projet et utiliser l’URL de point de terminaison de prédiction du projet pour le tester programmatiquement. Utilisez cet exemple comme modèle pour générer votre propre application de reconnaissance d’image.

Notes

Si vous souhaitez créer et entraîner un modèle de détection d’objets sans écrire de code, consultez à la place les instructions basées sur le navigateur.

Utilisez la bibliothèque de client Custom Vision pour Python pour :

  • Créer un projet de service Custom Vision
  • Ajouter des balises au projet
  • Charger et étiqueter des images
  • Entraîner le projet
  • Publier l’itération actuelle
  • Tester le point de terminaison de prédiction

Documentation de référence | Code source de la bibliothèque | Package (PyPI) | Exemples

Prérequis

  • Abonnement Azure - En créer un gratuitement
  • Python 3.x
    • Votre installation Python doit inclure pip. Vous pouvez vérifier si pip est installé en exécutant pip --version sur la ligne de commande. Procurez-vous pip en installant la dernière version de Python.
  • Une fois votre abonnement Azure obtenu, permet de créer une ressource Custom Vision dans le portail Azure pour créer une ressource de formation et de prévision.
    • Vous pouvez utiliser le niveau tarifaire Gratuit (F0) pour tester le service, puis passer par la suite à un niveau payant pour la production.

Créer des variables d’environnement

Dans cet exemple, vous allez écrire vos informations d’identification dans des variables d’environnement sur l’ordinateur local exécutant l’application.

Accédez au portail Azure. Si les ressources Custom Vision que vous avez créées dans la section Prérequis ont été déployées correctement, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous pouvez trouver vos clés et vos point de terminaison dans les pages Clés et point de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés pour vos ressources d’entraînement et de prédiction, ainsi que les points de terminaison d’API.

L’ID de ressource de prévision est disponible dans le portail Microsoft Azure, sous l’onglet Propriétés de la ressource, listé comme ID de ressource.

Conseil

Vous utilisez également https://www.customvision.ai pour obtenir ces valeurs. Après vous être connecté, sélectionnez l’icône Paramètres en haut à droite. Dans les pages de Paramètres, vous pouvez visualiser l’ensemble des clés, ID de ressource et points de terminaison.

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions relatives à votre système d’exploitation et à votre environnement de développement.

  • Pour définir la variable d’environnement VISION_TRAINING KEY, remplacez <your-training-key> par l’une des clés de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT, remplacez <your-training-endpoint> par le point de terminaison de votre ressource de formation.
  • Pour définir la variable d’environnement VISION_PREDICTION_KEY, remplacez <your-prediction-key> par l’une des clés de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT, remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prévision.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID, remplacez <your-resource-id> par l’ID de votre ressource de prévision.

Important

Si vous utilisez une clé API, stockez-la en toute sécurité dans un autre emplacement, par exemple dans Azure Key Vault. N'incluez pas la clé API directement dans votre code et ne la diffusez jamais publiquement.

Pour plus d’informations sur la sécurité des services IA, consultez Authentifier les demandes auprès d’Azure AI services.

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>

Une fois que vous avez ajouté les variables d’environnement, il peut être nécessaire de redémarrer tous les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de la console.

Configuration

Installer la bibliothèque de client

Pour écrire une application d’analyse d’image avec Custom Vision pour Python, vous avez besoin de la bibliothèque de client Custom Vision. Après l’installation de Python, exécutez la commande suivante dans PowerShell ou dans une fenêtre de console :

pip install azure-cognitiveservices-vision-customvision

Créer une application Python

Créez un fichier Python et importez les bibliothèques suivantes.

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

Conseil

Vous voulez voir l’intégralité du fichier de code de démarrage rapide à la fois ? Vous le trouverez sur GitHub, qui contient les exemples de code utilisés dans ce guide de démarrage rapide.

Créez des variables pour le point de terminaison et les clés Azure de votre ressource.

# 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"]

Modèle objet

Nom Description
CustomVisionTrainingClient Cette classe gère la création, l’entraînement et la publication de vos modèles.
CustomVisionPredictionClient Cette classe gère l’interrogation de vos modèles pour les prédictions de détection d’objets.
ImagePrediction Cette classe définit une prédiction d’objet unique sur une seule image. Elle comprend des propriétés pour l’ID et le nom de l’objet, la position du rectangle englobant de l’objet et un score de confiance.

Exemples de code

Ces extraits de code vous montrent comment effectuer les opérations suivantes avec la bibliothèque de client Custom Vision pour Python :

Authentifier le client

Instanciez un client d’entraînement et de prédiction à l’aide de votre point de terminaison et de vos clés. Créez des objets ApiKeyServiceClientCredentials avec vos clés et utilisez-les avec votre point de terminaison pour créer un objet CustomVisionTrainingClient et un objet 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)

Créer un projet de service Custom Vision

Pour créer un nouveau projet Service Vision personnalisée, ajoutez le code suivant à votre script.

Consultez la méthode create_project pour spécifier d’autres options quand vous créez votre projet (procédure expliquée dans le guide du portail web Build a detector [Créer un détecteur]).

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)

Ajouter des balises au projet

Pour créer des étiquettes d’objet dans votre projet, ajoutez le code suivant :

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

Charger et étiqueter des images

Tout d’abord, téléchargez les exemples d’images pour ce projet. Enregistrez le contenu du dossier des exemples d’images sur votre appareil local.

Lorsque vous appliquez des balises à des images dans des projets de détection d’objet, vous devez préciser la région de chaque objet balisé avec des coordonnées normalisées. Le code suivant associe chaque exemple d’image à sa région balisée. Les régions spécifient le niveau du bit dans des coordonnées normalisées, et ces dernières sont données dans l’ordre : gauche, haut, largeur et hauteur.

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 ]
}

Notes

Si vous n’avez pas d’utilitaire permettant d’effectuer des opérations de glisser-déposer pour marquer les coordonnées des régions, vous pouvez utiliser l’IU web sur Customvision.ai. Dans cet exemple, les coordonnées sont déjà fournies.

Utilisez alors cette carte d’associations pour charger chaque exemple d’image avec ses coordonnées de région (vous pouvez charger jusqu’à 64 images dans un même lot). Ajoutez le code ci-dessous.

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)

Notes

Vous devez changer le chemin des images, selon l’emplacement où vous avez préalablement téléchargé le référentiel d’exemples du kit de développement logiciel (SDK) Python d’Azure AI services.

Entraîner le projet

Ce code crée la première itération du modèle de prédiction.

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)

Conseil

Entraîner avec des étiquettes sélectionnées

Vous pouvez, si vous le souhaitez, effectuer l’entraînement sur un sous-ensemble de vos étiquettes appliquées. Vous pouvez procéder de la sorte si vous n’avez pas encore suffisamment appliqué certaines étiquettes, contrairement à d’autres. Dans l’appel train_project , définissez le paramètre facultatif selected_tags sur une liste de chaînes d’ID des étiquettes que vous souhaitez utiliser. Le modèle effectue l’entraînement pour ne reconnaître que les étiquettes présentes dans cette liste.

Publier l’itération actuelle

Les itérations ne sont pas disponibles sur le point de terminaison de prédiction tant qu’elles n’ont pas été publiées. Le code suivant rend l’itération actuelle du modèle disponible pour l’interrogation.

# 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!")

Tester le point de terminaison de prédiction

Pour envoyer une image au point de terminaison de prédiction et récupérer la prédiction, ajoutez le code suivant à la fin du fichier :

# 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))

Exécution de l'application

Exécutez CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

La sortie de l’application doit apparaître dans la console. Vous pouvez alors vérifier que l’image de test (qui se trouve dans <emplacement_image_de_base>/images/Test) est étiquetée de façon appropriée et que la région de détection est correcte. Vous pouvez aussi revenir sur le site web Custom Vision et consulter l’état actuel de votre nouveau projet.

Nettoyer les ressources

Si vous voulez implémenter votre projet de détection d’objets (ou essayer un projet de classification d’images), supprimez le projet de détection de fourchettes/ciseaux de cet exemple. Avec un abonnement gratuit, vous pouvez avoir deux projets Custom Vision.

Sur le site web Custom Vision, accédez à Projects (Projets) puis sélectionnez la corbeille sous My New Project (Nouveau projet).

Capture d’écran d’un panneau étiqueté Mon Nouveau Projet avec une icône de corbeille.

Étapes suivantes

Vous avez à présent effectué chaque étape du processus de détection d’objet dans le code. Cet exemple exécute une seule itération d’entraînement, mais vous aurez souvent besoin d’entraîner et de tester votre modèle à plusieurs reprises pour le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont identiques à la détection d’objet.