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

Prise en main de la bibliothèque cliente Custom Vision pour .NET. Suivez ces étapes pour installer le package et essayer l’exemple de code permettant de créer un modèle de détection d’objet. Vous allez créer un projet, ajouter des balises, entraîner le projet sur des exemples d’images et utiliser l’URL du point de terminaison de prédiction du projet pour le tester par programmation. Utilisez cet exemple comme modèle pour créer votre propre application de reconnaissance d’image.

Note

Si vous souhaitez générer et entraîner un modèle de détection d’objet sans écrire de code, consultez plutôt les instructions basées sur le navigateur .

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

Conditions préalables

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 Conditions préalables déployées avec succès, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous trouverez vos clés et points de terminaison dans les pages Clés et points de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés de votre ressource d’entraînement et de votre ressource de prédiction, ainsi que les points de terminaison d’API.

Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié sous la forme Resource ID.

Conseil

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

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions de votre système d’exploitation et de 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 d’apprentissage.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT , remplacez <your-training-endpoint> par le point de terminaison de votre ressource d’entraînement.
  • 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édiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT , remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prédiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID , remplacez <your-resource-id> par l’ID de ressource de votre ressource de prédiction.

Important

Nous vous recommandons l'authentification Microsoft Entra ID avec les identités managées pour les ressources Azure pour éviter de stocker les identifiants avec vos applications qui s'exécutent dans le cloud.

Utilisez des clés API avec précaution. N’incluez pas la clé API directement dans votre code et ne la publiez jamais publiquement. Si vous utilisez des clés API, stockez-les en toute sécurité dans Azure Key Vault, faites pivoter les clés régulièrement et limitez l’accès aux Azure Key Vault à l’aide du contrôle d’accès en fonction du rôle et des restrictions d’accès réseau. Pour plus d’informations sur l’utilisation sécurisée des clés API dans vos applications, consultez les API avec Azure Key Vault.

Pour plus d’informations sur la sécurité des services d’INTELLIGENCE artificielle, consultez Demandes d’authentification à 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>

Après avoir ajouté les variables d’environnement, vous devrez peut-être redémarrer les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de console.

Mise en place

Créer une application C#

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

Installer la bibliothèque cliente

Une fois que vous avez créé un projet, installez la bibliothèque cliente en cliquant avec le bouton droit sur la solution de projet dans le Explorateur de solutions et en sélectionnant Manage nuGet Packages. Dans le gestionnaire de package qui s’ouvre, sélectionnez Browse, vérifiez Include prerelease et recherchez Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training et Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Sélectionnez la dernière version, puis installez.

Conseil

Vous souhaitez afficher l’ensemble du fichier de code de démarrage rapide à la fois ? Vous pouvez le trouver sur GitHub qui contient les exemples de code de ce guide de démarrage rapide.

Dans le répertoire du projet, ouvrez le fichier program.cs et ajoutez les directives suivantes using :

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

Dans la méthode Main de l’application, créez des variables qui récupèrent les clés et le point de terminaison de votre ressource à partir de variables d’environnement. Vous allez également déclarer certains 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 allez les implémenter 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, utilisez votre endpoint et vos clés pour instancier les clients d’entraînement et de prédiction.

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 Custom Vision

Cette méthode suivante crée un projet de détection d’objet. Le projet créé s’affiche sur le site web Custom Vision. Consultez la méthode CreateProject pour spécifier d’autres options lorsque vous créez votre projet (expliqué dans le guide générer un portail web 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 balises sur lesquelles vous allez entraîner le 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 sample Images sur votre appareil local.

Lorsque vous étiquetez des images dans des projets de détection d’objets, vous devez spécifier la région de chaque objet étiqueté à l’aide de coordonnées normalisées. Le code suivant associe chacun des exemples d’images à sa région marqué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 } }
    };

Note

Pour vos propres projets, si vous n’avez pas d’utilitaire de clic et de glisser pour marquer les coordonnées des régions, vous pouvez utiliser l’interface utilisateur web sur le site web Custom Vision. Dans cet exemple, les coordonnées sont déjà fournies.

Ensuite, cette carte d’associations est utilisée pour charger chaque exemple d’image avec ses coordonnées de région. Vous pouvez charger jusqu’à 64 images dans un seul lot. Vous devrez peut-être modifier la imagePath valeur pour qu’elle pointe vers les emplacements de dossiers 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é toutes les images d’exemples et étiqueté chacune d’elles (fourche ou ciseaux) avec un rectangle de pixel associé.

Entraîner le projet

Cette méthode crée la première itération d’entraînement dans le projet. Il interroge le service jusqu’à ce que la formation soit terminée.

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

S'entraîner avec des balises sélectionnées

Vous pouvez éventuellement effectuer l’apprentissage uniquement sur un sous-ensemble de vos balises appliquées. Vous pouvez le faire si vous n’avez pas encore appliqué suffisamment de certaines balises, mais vous avez assez 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 balises que vous souhaitez utiliser. Le modèle s’entraîne pour reconnaître uniquement les étiquettes de 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. Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié en tant qu'ID Resource ID.

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 de test, interroge le point de terminaison du modèle et génère des données de prédiction dans 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écuter l’application

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

Lorsque l’application s’exécute, elle doit ouvrir une fenêtre de console et écrire la sortie suivante :

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 ensuite vérifier que l’image de test (trouvée dans Images/Test/) est étiquetée de manière 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 souhaitez implémenter votre propre projet de détection d’objet (ou essayer un projet de classification d’images à la place), vous pouvez supprimer le projet de détection du fork/scissors de cet exemple. Un abonnement gratuit permet de créer deux projets dans Custom Vision.

Sur le site web Custom Vision, accédez à Projects et sélectionnez la corbeille sous Mon nouveau Project.

Screenshot d’un panneau intitulé

Étapes suivantes

Vous avez maintenant 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 devez souvent entraîner et tester votre modèle plusieurs fois afin de le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont similaires à la détection d’objets.

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

Note

Si vous souhaitez générer et entraîner un modèle de détection d’objet sans écrire de code, consultez plutôt les instructions basées sur le navigateur .

Documentation de référence (formation)(prédiction)

Conditions préalables

  • Abonnement Azure - Créez-en un gratuitement
  • Accédez à 1,8+
  • Une fois que vous avez votre abonnement Azure, créer une ressource Custom Vision dans le portail Azure pour créer une ressource de formation et de prédiction.
    • Vous pouvez utiliser le niveau tarifaire gratuit (F0) pour essayer le service et effectuer une mise à niveau ultérieure vers 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 Conditions préalables déployées avec succès, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous trouverez vos clés et points de terminaison dans les pages Clés et points de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés de votre ressource d’entraînement et de votre ressource de prédiction, ainsi que les points de terminaison d’API.

Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié sous la forme Resource ID.

Conseil

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

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions de votre système d’exploitation et de 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 d’apprentissage.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT , remplacez <your-training-endpoint> par le point de terminaison de votre ressource d’entraînement.
  • 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édiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT , remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prédiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID , remplacez <your-resource-id> par l’ID de ressource de votre ressource de prédiction.

Important

Nous vous recommandons l'authentification Microsoft Entra ID avec les identités managées pour les ressources Azure pour éviter de stocker les identifiants avec vos applications qui s'exécutent dans le cloud.

Utilisez des clés API avec précaution. N’incluez pas la clé API directement dans votre code et ne la publiez jamais publiquement. Si vous utilisez des clés API, stockez-les en toute sécurité dans Azure Key Vault, faites pivoter les clés régulièrement et limitez l’accès aux Azure Key Vault à l’aide du contrôle d’accès en fonction du rôle et des restrictions d’accès réseau. Pour plus d’informations sur l’utilisation sécurisée des clés API dans vos applications, consultez les API avec Azure Key Vault.

Pour plus d’informations sur la sécurité des services d’INTELLIGENCE artificielle, consultez Demandes d’authentification à 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>

Après avoir ajouté les variables d’environnement, vous devrez peut-être redémarrer les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de console.

Mise en place

Installer la bibliothèque de client Custom Vision

Pour écrire une application d’analyse d’images avec Custom Vision pour Go, vous aurez besoin de la bibliothèque cliente 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, exécutez cette commande dans votre dépôt :

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

Obtenir les exemples d’images

Cet exemple utilise les images du référentiel Foundry Tools Python SDK Samples sur GitHub. Clonez ou téléchargez ce référentiel dans votre environnement de développement. N’oubliez pas l’emplacement de son dossier pour une étape ultérieure.

Créer le projet Custom Vision

Créez un fichier appelé sample.go dans votre répertoire de projet préféré, puis ouvrez-le dans votre éditeur de code préféré.

Ajoutez le code suivant à votre script pour créer un projet de service Custom Vision.

Consultez la méthode CreateProject pour spécifier d’autres options lorsque vous créez votre projet (expliqué dans le guide générer un portail web 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 le projet

Pour créer des balises de classification dans votre projet, ajoutez le code suivant à la fin de 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 étiquetez des images dans des projets de détection d’objets, vous devez spécifier la région de chaque objet étiqueté à l’aide de coordonnées normalisées.

Note

Si vous n’avez pas d’utilitaire de clic et de glisser pour marquer les coordonnées des régions, vous pouvez utiliser l’interface utilisateur web à Customvision.ai. Dans cet exemple, les coordonnées sont déjà fournies.

Pour ajouter les images, balises et régions au projet, insérez le code suivant après la création de la balise. Notez que dans ce didacticiel, les régions sont codées en dur en ligne. Les régions spécifient la boîte englobante dans des coordonnées normalisées, et les coordonnées sont indiquées dans l’ordre : gauche, haut, largeur, 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 },
}

Ensuite, utilisez 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 seul lot). Ajoutez le code suivant.

Note

Vous devrez modifier le chemin vers les images en fonction de l’emplacement où vous avez téléchargé précédemment le projet d'exemples du SDK Go des Outils Foundry.

// 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 demandes de prédiction. Une itération n’est pas disponible dans 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écuter l’application

Exécutez sample.go.

go run sample.go

La sortie de l’application doit apparaître dans la console. Vous pouvez ensuite vérifier que l’image de test (trouvée dans des exemples/vision/images/test) est étiquetée de manière appropriée et que la région de détection est correcte.

Nettoyer les ressources

Si vous souhaitez implémenter votre propre projet de détection d’objet (ou essayer un projet de classification d’images à la place), vous pouvez supprimer le projet de détection du fork/scissors de cet exemple. Un abonnement gratuit permet de créer deux projets dans Custom Vision.

Sur le site web Custom Vision, accédez à Projects et sélectionnez la corbeille sous Mon nouveau Project.

Screenshot d’un panneau intitulé

Étapes suivantes

Vous avez maintenant 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 devez souvent entraîner et tester votre modèle plusieurs fois afin de le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont similaires à la détection d’objets.

Commencez à utiliser la bibliothèque cliente Custom Vision pour Java pour créer un modèle de détection d’objet. Suivez ces étapes pour installer le package et essayer l’exemple de code pour les tâches de base. Utilisez cet exemple comme modèle pour créer votre propre application de reconnaissance d’image.

Note

Si vous souhaitez générer et entraîner un modèle de détection d’objet sans écrire de code, consultez plutôt les instructions basées sur le navigateur .

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

Conditions préalables

  • Un abonnement Azure - Create one gratuitement
  • La version actuelle du kit de développement Java(JDK)
  • L’outil de génération Gradle ou un autre gestionnaire de dépendances.
  • Une fois que vous avez votre abonnement Azure, créer une ressource Custom Vision dans le portail Azure pour créer une ressource de formation et de prédiction.
    • Vous pouvez utiliser le niveau tarifaire gratuit (F0) pour essayer le service et effectuer une mise à niveau ultérieure vers 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 Conditions préalables déployées avec succès, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous trouverez vos clés et points de terminaison dans les pages Clés et points de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés de votre ressource d’entraînement et de votre ressource de prédiction, ainsi que les points de terminaison d’API.

Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié sous la forme Resource ID.

Conseil

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

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions de votre système d’exploitation et de 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 d’apprentissage.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT , remplacez <your-training-endpoint> par le point de terminaison de votre ressource d’entraînement.
  • 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édiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT , remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prédiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID , remplacez <your-resource-id> par l’ID de ressource de votre ressource de prédiction.

Important

Nous vous recommandons l'authentification Microsoft Entra ID avec les identités managées pour les ressources Azure pour éviter de stocker les identifiants avec vos applications qui s'exécutent dans le cloud.

Utilisez des clés API avec précaution. N’incluez pas la clé API directement dans votre code et ne la publiez jamais publiquement. Si vous utilisez des clés API, stockez-les en toute sécurité dans Azure Key Vault, faites pivoter les clés régulièrement et limitez l’accès aux Azure Key Vault à l’aide du contrôle d’accès en fonction du rôle et des restrictions d’accès réseau. Pour plus d’informations sur l’utilisation sécurisée des clés API dans vos applications, consultez les API avec Azure Key Vault.

Pour plus d’informations sur la sécurité des services d’INTELLIGENCE artificielle, consultez Demandes d’authentification à 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>

Après avoir ajouté les variables d’environnement, vous devrez peut-être redémarrer les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de console.

Mise en place

Créer un projet Gradle

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

mkdir myapp && cd myapp

Exécutez la gradle init commande à 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é lors de l’exécution pour créer et configurer votre application.

gradle init --type basic

Lorsque vous êtes invité à choisir une DSL, sélectionnez Kotlin.

Installer la bibliothèque cliente

Recherchez build.gradle.kts et ouvrez-le avec votre IDE ou éditeur de texte préféré. Copiez ensuite dans la configuration de build suivante. Cette configuration définit le projet comme une application Java dont le point d’entrée est la classe CustomVisionQuickstart. Il 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

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

mkdir -p src/main/java

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

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

import com.google.common.io.ByteStreams;

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

Conseil

Vous souhaitez afficher l’ensemble du fichier de code de démarrage rapide à la fois ? Vous pouvez le trouver sur GitHub qui contient les exemples de code de 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 le point 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 principale 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 cliente Custom Vision Java.

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. Il inclut les propriétés de l’ID et du nom de l’objet, de l’emplacement de la boîte englobante de l’objet et d’un score de confiance.

Exemples de code

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

Authentifier le client

Dans votre méthode principale , instanciez les clients de formation 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 Custom Vision

Cette méthode suivante crée un projet de détection d’objet. Le projet créé s’affiche sur le site web Custom Vision que vous avez visité précédemment. Consultez les surcharges de méthode CreateProject pour spécifier d’autres options lorsque vous créez votre projet (expliqué dans le guide générer un portail web 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 balises à votre projet

Cette méthode définit les balises sur lesquelles vous allez entraîner le 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 sample Images sur votre appareil local.

Note

Avez-vous besoin d’un ensemble plus large d’images pour terminer votre formation ? Trove, un projet de garage Microsoft, vous permet de collecter et d’acheter des ensembles d’images à des fins de formation. 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. Visitez la page Trove pour en savoir plus.

Lorsque vous étiquetez des images dans des projets de détection d’objets, vous devez spécifier la région de chaque objet étiqueté à l’aide de coordonnées normalisées. Le code suivant associe chacun des exemples d’images à sa région marquée.

Note

Si vous n’avez pas d’utilitaire de clic et de glisser pour marquer les coordonnées des régions, vous pouvez utiliser l’interface utilisateur web à 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 modifier les arguments des appels de GetImage pour pointer vers les emplacements des dossiers fourchette et ciseaux 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 en tant que flux de ressources et les chargent dans le service (vous pouvez charger jusqu’à 64 images dans un lot unique). 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. Il interroge le service jusqu’à ce que la formation soit terminée.

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. Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié en tant qu'ID Resource ID.

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 de test, interroge le point de terminaison du modèle et génère des données de prédiction dans 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écuter l’application

Vous pouvez créer l’application avec :

gradle build

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

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 supprime également toutes les autres ressources associées.

Si vous souhaitez implémenter votre propre projet de détection d’objet (ou essayer un projet de classification d’images à la place), vous pouvez supprimer le projet de détection du fork/scissors de cet exemple. Un abonnement gratuit permet de créer deux projets dans Custom Vision.

Sur le site web Custom Vision, accédez à Projects et sélectionnez la corbeille sous Mon nouveau Project.

Screenshot d’un panneau intitulé

Étapes suivantes

Vous avez maintenant 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 devez souvent entraîner et tester votre modèle plusieurs fois afin de le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont similaires à la détection d’objets.

Ce guide fournit des instructions et des exemples de code pour vous aider à commencer à utiliser la bibliothèque cliente Custom Vision pour Node.js pour générer un modèle de détection d’objet. Vous créez un projet, ajoutez des balises, entraînez le projet et utilisez l’URL du point de terminaison de prédiction du projet pour le tester par programmation. Utilisez cet exemple comme modèle pour créer votre propre application de reconnaissance d’image.

Note

Si vous souhaitez générer et entraîner un modèle de détection d’objet sans écrire de code, consultez plutôt les instructions basées sur le navigateur .

Documentation de référence (formation)(prédiction) | Package (npm) (formation)(prédiction) | Exemples

Conditions préalables

  • Abonnement Azure - Créez-en un gratuitement
  • Version actuelle de Node.js
  • Une fois que vous avez votre abonnement Azure, créer une ressource Custom Vision dans le portail Azure pour créer une ressource de formation et de prédiction.
    • Vous pouvez utiliser le niveau tarifaire gratuit (F0) pour essayer le service et effectuer une mise à niveau ultérieure vers 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 Conditions préalables déployées avec succès, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous trouverez vos clés et points de terminaison dans les pages Clés et points de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés de votre ressource d’entraînement et de votre ressource de prédiction, ainsi que les points de terminaison d’API.

Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié sous la forme Resource ID.

Conseil

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

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions de votre système d’exploitation et de 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 d’apprentissage.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT , remplacez <your-training-endpoint> par le point de terminaison de votre ressource d’entraînement.
  • 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édiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT , remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prédiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID , remplacez <your-resource-id> par l’ID de ressource de votre ressource de prédiction.

Important

Nous vous recommandons l'authentification Microsoft Entra ID avec les identités managées pour les ressources Azure pour éviter de stocker les identifiants avec vos applications qui s'exécutent dans le cloud.

Utilisez des clés API avec précaution. N’incluez pas la clé API directement dans votre code et ne la publiez jamais publiquement. Si vous utilisez des clés API, stockez-les en toute sécurité dans Azure Key Vault, faites pivoter les clés régulièrement et limitez l’accès aux Azure Key Vault à l’aide du contrôle d’accès en fonction du rôle et des restrictions d’accès réseau. Pour plus d’informations sur l’utilisation sécurisée des clés API dans vos applications, consultez les API avec Azure Key Vault.

Pour plus d’informations sur la sécurité des services d’INTELLIGENCE artificielle, consultez Demandes d’authentification à 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>

Après avoir ajouté les variables d’environnement, vous devrez peut-être redémarrer les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de console.

Mise en place

Créer une application Node.js

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

mkdir myapp && cd myapp

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

npm init

Installer la bibliothèque cliente

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 est 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 souhaitez afficher l’ensemble du fichier de code de démarrage rapide à la fois ? Vous pouvez le trouver sur GitHub qui contient les exemples de code de 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’expiration 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. Il inclut 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 cliente Custom Vision pour JavaScript :

Authentifier le client

Instanciez des objets clients avec votre point de terminaison et votre clé. Créez un objet ApiKeyCredentials avec votre clé et utilisez-le avec votre point de terminaison pour créer un objet TrainingAPIClient et 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 vous aider à effectuer 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 Custom Vision

Lancez une nouvelle fonction pour regrouper 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 balises 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 sample Images sur votre appareil local.

Pour ajouter les exemples d’images au projet, insérez le code suivant après la création de la balise. Ce code charge chaque image avec sa balise correspondante. Lorsque vous étiquetez des images dans des projets de détection d’objets, vous devez spécifier la région de chaque objet étiqueté à l’aide de coordonnées normalisées. Pour ce didacticiel, les régions sont codées en dur avec le code. Les régions spécifient la boîte englobante dans des coordonnées normalisées, et les coordonnées sont indiquées dans l’ordre : gauche, haut, largeur, hauteur. Vous pouvez charger jusqu’à 64 images dans un seul 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 modifier le chemin d’accès aux images (sampleDataRoot) en fonction de l’emplacement où vous avez téléchargé le dépôt d’exemples du Kit de développement logiciel (SDK) Foundry Tools Python.

Note

Si vous n’avez pas d’utilitaire de clic et de glisser pour marquer les coordonnées des régions, vous pouvez utiliser l’interface utilisateur web à 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 demandes de prédiction. Une itération n’est pas disponible dans le point de terminaison de prédiction tant qu’elle n’est pas publiée.

// 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écuter l’application

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

node index.js

La sortie de l’application doit apparaître dans la console. Vous pouvez ensuite vérifier que l’image de test (trouvée dans <sampleDataRoot>/Test/) est étiquetée de manière appropriée et que la région de détection est correcte. Vous pouvez également revenir au site web Custom Vision et voir l’état actuel de votre projet nouvellement créé.

Nettoyer les ressources

Si vous souhaitez implémenter votre propre projet de détection d’objet (ou essayer un projet de classification d’images à la place), vous pouvez supprimer le projet de détection du fork/scissors de cet exemple. Un abonnement gratuit permet de créer deux projets dans Custom Vision.

Sur le site web Custom Vision, accédez à Projects et sélectionnez la corbeille sous Mon nouveau Project.

Screenshot d’un panneau intitulé

Étapes suivantes

Vous avez maintenant 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 devez souvent entraîner et tester votre modèle plusieurs fois afin de le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont similaires à la détection d’objets.

Prise en main de la bibliothèque de client Custom Vision pour Python. Suivez ces étapes pour installer le package et essayer l’exemple de code permettant de créer un modèle de détection d’objet. Vous créez un projet, ajoutez des balises, entraînez le projet et utilisez l’URL du point de terminaison de prédiction du projet pour le tester par programmation. Utilisez cet exemple comme modèle pour créer votre propre application de reconnaissance d’image.

Note

Si vous souhaitez générer et entraîner un modèle de détection d’objet sans écrire de code, consultez plutôt les instructions basées sur le navigateur .

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

Conditions préalables

  • Abonnement Azure - Créez-en un gratuitement
  • Python 3.x
    • Votre installation de Python doit inclure pip. Vous pouvez vérifier si pip est installé en exécutant pip --version la ligne de commande. Obtenez pip en installant la dernière version de Python.
  • Une fois que vous avez votre abonnement Azure, créer une ressource Custom Vision dans le portail Azure pour créer une ressource de formation et de prédiction.
    • Vous pouvez utiliser le niveau tarifaire gratuit (F0) pour essayer le service et effectuer une mise à niveau ultérieure vers 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 Conditions préalables déployées avec succès, sélectionnez le bouton Accéder à la ressource sous Étapes suivantes. Vous trouverez vos clés et points de terminaison dans les pages Clés et points de terminaison des ressources, sous Gestion des ressources. Vous devez obtenir les clés de votre ressource d’entraînement et de votre ressource de prédiction, ainsi que les points de terminaison d’API.

Vous trouverez l'ID de ressource de prédiction sous l'onglet Properties dans le portail Azure, répertorié sous la forme Resource ID.

Conseil

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

Pour définir les variables d’environnement, ouvrez une fenêtre de console et suivez les instructions de votre système d’exploitation et de 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 d’apprentissage.
  • Pour définir la variable d’environnement VISION_TRAINING_ENDPOINT , remplacez <your-training-endpoint> par le point de terminaison de votre ressource d’entraînement.
  • 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édiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_ENDPOINT , remplacez <your-prediction-endpoint> par le point de terminaison de votre ressource de prédiction.
  • Pour définir la variable d’environnement VISION_PREDICTION_RESOURCE_ID , remplacez <your-resource-id> par l’ID de ressource de votre ressource de prédiction.

Important

Nous vous recommandons l'authentification Microsoft Entra ID avec les identités managées pour les ressources Azure pour éviter de stocker les identifiants avec vos applications qui s'exécutent dans le cloud.

Utilisez des clés API avec précaution. N’incluez pas la clé API directement dans votre code et ne la publiez jamais publiquement. Si vous utilisez des clés API, stockez-les en toute sécurité dans Azure Key Vault, faites pivoter les clés régulièrement et limitez l’accès aux Azure Key Vault à l’aide du contrôle d’accès en fonction du rôle et des restrictions d’accès réseau. Pour plus d’informations sur l’utilisation sécurisée des clés API dans vos applications, consultez les API avec Azure Key Vault.

Pour plus d’informations sur la sécurité des services d’INTELLIGENCE artificielle, consultez Demandes d’authentification à 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>

Après avoir ajouté les variables d’environnement, vous devrez peut-être redémarrer les programmes en cours d’exécution qui lisent les variables d’environnement, y compris la fenêtre de console.

Mise en place

Installer la bibliothèque cliente

Pour écrire une application d’analyse d’images avec Custom Vision pour Python, vous avez besoin de la bibliothèque cliente Custom Vision. Après avoir installé Python, exécutez la commande suivante dans PowerShell ou 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 souhaitez afficher l’ensemble du fichier de code de démarrage rapide à la fois ? Vous pouvez le trouver sur GitHub qui contient les exemples de code de 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 vprediction_endpointalid values
ENDPOINT = os.environ["VISION_TRAINING_ENDPOINT"]
prediction_endpoint = os.environ["VISION_PREDICTION_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. Il inclut les propriétés de l’ID et du nom de l’objet, de l’emplacement de la boîte englobante de l’objet et d’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 avec votre point de terminaison et 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 CustomVisionPredictionClient .

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

Créer un projet Custom Vision

Ajoutez le code suivant à votre script pour créer un projet de service Custom Vision.

Consultez la méthode create_project pour spécifier d’autres options lorsque vous créez votre projet (expliqué dans le guide générer un portail web 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 balises 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 sample Images sur votre appareil local.

Lorsque vous étiquetez des images dans des projets de détection d’objets, vous devez spécifier la région de chaque objet étiqueté à l’aide de coordonnées normalisées. Le code suivant associe chacun des exemples d’images à sa région marquée. Les régions spécifient la boîte englobante dans des coordonnées normalisées, et les coordonnées sont indiquées dans l’ordre : gauche, haut, largeur, 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 ]
}

Note

Si vous n’avez pas d’utilitaire de clic et de glisser pour marquer les coordonnées des régions, vous pouvez utiliser l’interface utilisateur web à Customvision.ai. Dans cet exemple, les coordonnées sont déjà fournies.

Ensuite, utilisez 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 seul lot). Ajoutez le code suivant.

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)

Note

Vous devez modifier le chemin d'accès aux images en fonction de l'emplacement où vous avez téléchargé le dépôt d'exemples de SDK Foundry Tools Python précédemment.

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

S'entraîner avec des balises sélectionnées

Vous pouvez éventuellement effectuer l’apprentissage uniquement sur un sous-ensemble de vos balises appliquées. Vous pouvez le faire si vous n’avez pas encore appliqué suffisamment de certaines balises, mais vous avez assez d’autres. Dans l’appel train_project , définissez le paramètre facultatif selected_tags sur une liste des chaînes d’ID des balises que vous souhaitez utiliser. Le modèle s’entraîne pour reconnaître uniquement les étiquettes de cette liste.

Publier l’itération actuelle

Une itération n’est pas disponible dans le point de terminaison de prédiction tant qu’elle n’est pas publiée. 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écuter l’application

Exécutez CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

La sortie de l’application doit apparaître dans la console. Vous pouvez ensuite vérifier que l’image de test (trouvée dans <base_image_location>/images/Test) est étiquetée de manière appropriée et que la région de détection est correcte. Vous pouvez également revenir au site web Custom Vision et voir l’état actuel de votre projet nouvellement créé.

Nettoyer les ressources

Si vous souhaitez implémenter votre propre projet de détection d’objet (ou essayer un projet de classification d’images à la place), vous pouvez supprimer le projet de détection du fork/scissors de cet exemple. Un abonnement gratuit permet de créer deux projets dans Custom Vision.

Sur le site web Custom Vision, accédez à Projects et sélectionnez la corbeille sous Mon nouveau Project.

Screenshot d’un panneau intitulé

Étapes suivantes

Vous avez maintenant 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 devez souvent entraîner et tester votre modèle plusieurs fois afin de le rendre plus précis. Le guide suivant traite de la classification d’images, mais ses principes sont similaires à la détection d’objets.