Guida introduttiva: Creare un progetto di rilevamento oggetti con la libreria client di Visione personalizzata

Introduzione alla libreria client di Visione personalizzata per .NET. Seguire questi passaggi per installare il pacchetto e provare il codice di esempio per creare un modello di rilevamento oggetti. Si creerà un progetto, si aggiungeranno i tag, si eseguirà il training del progetto con le immagini di esempio e si userà l'URL dell'endpoint di previsione del progetto per testarlo a livello di codice. Usare questo esempio come modello per la creazione di un'app di riconoscimento immagini personalizzata.

Nota

Se si intende creare un modello di rilevamento oggetti ed eseguirne il training senza scrivere codice, vedere invece le indicazioni basate sul browser.

Documentazione di riferimento | Codice sorgente della libreria (training)(previsione) | Pacchetti (NuGet) (training)(prediction) | Samples

Prerequisiti

Creare variabili di ambiente

In questo esempio si scriveranno le credenziali nelle variabili di ambiente nel computer locale che esegue l'applicazione.

Vai al portale di Azure. Se le risorse Visione personalizzata create nella sezione Prerequisiti sono state distribuite correttamente, selezionare il pulsante Vai alla risorsa in Passaggi successivi. È possibile trovare le chiavi e gli endpoint nelle pagine chiave ed endpoint delle risorse, in Gestione risorse. È necessario ottenere le chiavi sia per le risorse di training che per le risorse di stima, insieme agli endpoint API.

È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa di stima nella portale di Azure, elencata come ID risorsa.

Suggerimento

È anche possibile usare https://www.customvision.ai/ per ottenere questi valori. Dopo aver eseguito l'accesso, selezionare l'icona Impostazioni in alto a destra. Nelle pagine Impostazione è possibile visualizzare tutte le chiavi, l'ID risorsa e gli endpoint.

Attenzione

Non includere la chiave direttamente nel codice e non pubblicarla pubblicamente. Per altre opzioni di autenticazione come Azure Key Vault, vedere l'articolo sicurezza dei servizi di intelligenza artificiale di Azure.

Per impostare le variabili di ambiente, aprire una finestra della console e seguire le istruzioni per il sistema operativo e l'ambiente di sviluppo.

  1. Per impostare la VISION_TRAINING KEY variabile di ambiente, sostituire your-training-key con una delle chiavi per la risorsa di training.
  2. Per impostare la VISION_TRAINING_ENDPOINT variabile di ambiente, sostituire your-training-endpoint con l'endpoint per la risorsa di training.
  3. Per impostare la VISION_PREDICTION_KEY variabile di ambiente, sostituire your-prediction-key con una delle chiavi per la risorsa di stima.
  4. Per impostare la VISION_PREDICTION_ENDPOINT variabile di ambiente, sostituire your-prediction-endpoint con l'endpoint per la risorsa di stima.
  5. Per impostare la VISION_PREDICTION_RESOURCE_ID variabile di ambiente, sostituire your-resource-id con l'ID risorsa per la risorsa di stima.
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

Dopo aver aggiunto le variabili di ambiente, potrebbe essere necessario riavviare tutti i programmi in esecuzione che leggeranno le variabili di ambiente, inclusa la finestra della console.

Configurazione

Creare una nuova applicazione C#

Creare un'applicazione .NET Core con Visual Studio.

Installare la libreria client

Dopo aver creato un nuovo progetto, installare la libreria client facendo clic con il pulsante destro del mouse sulla soluzione del progetto in Esplora soluzioni e scegliendo Gestisci pacchetti NuGet. Nella finestra di dialogo Gestione pacchetti visualizzata selezionare Sfoglia, Includi versione preliminare e cercare Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training e Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Selezionare la versione più recente e fare clic su Installa.

Suggerimento

Si vuole visualizzare l'intero file di codice dell'argomento di avvio rapido? È possibile trovarlo in GitHub, che contiene gli esempi di codice di questo argomento.

Dalla directory del progetto aprire il file program.cs e aggiungere le direttive using seguenti:

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;

Nel metodo Main dell'applicazione creare variabili che recuperano le chiavi e l'endpoint della risorsa dalle variabili di ambiente. Verranno inoltre dichiarati alcuni oggetti di base da usare in un secondo momento.

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

Nel metodo Main dell'applicazione aggiungere le chiamate per i metodi usati in questa guida di avvio rapido. Queste verranno implementate in un secondo momento.

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

Autenticare il client

In un nuovo metodo, creare un'istanza dei client di training e di previsione usando l'endpoint e le chiavi.

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

Creare un nuovo progetto Visione personalizzata

Il metodo successivo crea un progetto di rilevamento di oggetti. Il progetto creato verrà visualizzato nel sito Web di Visione personalizzata. Per specificare altre opzioni quando si crea il progetto, come illustrato in Creare un rilevatore nella guida al portale Web, vedere il metodo CreateProject.

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

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

    return project;
}

Aggiungere tag al progetto

Questo metodo definisce i tag su cui si eseguirà il training del modello.

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

Caricare e contrassegnare le immagini

Scaricare prima di tutto le immagini di esempio per questo progetto. Salvare il contenuto della cartella immagini di esempio nel dispositivo locale.

Quando si aggiungono tag alle immagini nei progetti di rilevamento degli oggetti, è necessario specificare l'area di ogni oggetto contrassegnato usando coordinate normalizzate. Il codice seguente associa ognuna delle immagini di esempio alla relativa area contrassegnata.

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

Nota

Se per i progetti personali non è disponibile un'utilità di clic e trascinamento per contrassegnare le coordinate delle aree, è possibile usare l'interfaccia utente Web nel sito Web di Visione personalizzata. In questo esempio le coordinate sono già disponibili.

Quindi, questa mappa di associazioni viene usata per caricare ogni immagine di esempio con le relative coordinate di area. È possibile caricare fino a 64 immagini in un singolo batch. Potrebbe essere necessario modificare il valore di imagePath in modo che punti ai percorsi di cartella corretti.

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

A questo punto, tutte le immagini di esempio sono state caricate e sono stati aggiunti i tag a ogni immagine (forchetta o forbici) con un rettangolo di pixel associato.

Eseguire il training del progetto

Questo metodo crea la prima iterazione di training nel progetto. Esegue una query sul servizio fino al completamento del training.

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

Suggerimento

Eseguire il training con i tag selezionati

Facoltativamente, è possibile eseguire il training solo su un subset dei tag applicati. Questa operazione può essere eseguita se non è ancora stato applicato un numero sufficiente di determinati tag, ma si dispone di un numero sufficiente di altri. Nella chiamata TrainProject usare il parametro trainingParameters. Costruire un TrainingParameters e impostare la relativa proprietà SelectedTags su un elenco di ID dei tag che si intende usare. Il modello eseguirà il training in modo da riconoscere solo i tag nell'elenco.

Pubblicare l'iterazione corrente

Questo metodo rende disponibile l'iterazione corrente del modello per l'esecuzione di query. È possibile usare il nome del modello come riferimento per inviare richieste di previsione. È necessario immettere il valore corrente per predictionResourceId. È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa nella portale di Azure, elencata come ID risorsa.

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

Testare l'endpoint di stima

Questo metodo carica l'immagine di test, esegue query sull'endpoint del modello e restituisce i dati di stima nella 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();
}

Eseguire l'applicazione

Eseguire l'applicazione facendo clic sul pulsante Debug nella parte superiore della finestra dell'ambiente di sviluppo integrato.

Quando l'applicazione viene eseguita, dovrebbe aprire una finestra della console e scrivere l'output seguente:

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 ]

È quindi possibile verificare che l'immagine di test (disponibile in Images/Test/) sia contrassegnata in modo appropriato e che l'area di rilevamento sia corretta. A questo punto si può premere un tasto qualsiasi per uscire dall'applicazione.

Pulire le risorse

Se si vuole implementare il proprio progetto di rilevamento degli oggetti (o provare un progetto di classificazione delle immagini), è possibile eliminare il progetto di rilevamento di forchette/forbici da questo esempio. Una sottoscrizione gratuita consente di creare due progetti di Visione personalizzata.

Nel sito Web di Visione personalizzata passare a Projects e selezionare l'icona del cestino sotto My New Project.

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

Passaggi successivi

A questo punto è stato eseguito ogni passaggio del processo di rilevamento degli oggetti nel codice. Questo esempio esegue una sola iterazione del training, ma spesso è necessario eseguire il training e il test del modello più volte per ottenere una maggiore precisione. La guida seguente è incentrata sulla classificazione delle immagini, ma i principi sono simili a quelli del rilevamento di oggetti.

Questa guida fornisce istruzioni e codice di esempio per iniziare a usare la libreria client di Visione personalizzata per Go per creare un modello di rilevamento oggetti. Si creerà un progetto, si aggiungeranno tag, si eseguirà il training del progetto e si userà l'URL dell'endpoint di stima del progetto per testarlo a livello di codice. Usare questo esempio come modello per la creazione di un'app di riconoscimento immagini personalizzata.

Nota

Se si intende creare un modello di rilevamento oggetti ed eseguirne il training senza scrivere codice, vedere invece le indicazioni basate sul browser.

Usare la libreria client Visione personalizzata per Vai a:

  • Creare un nuovo progetto Visione personalizzata
  • Aggiungere tag al progetto
  • Caricare e contrassegnare le immagini
  • Eseguire il training del progetto
  • Pubblicare l'iterazione corrente
  • Testare l'endpoint di stima

Documentazione di riferimento (training)(previsione)

Prerequisiti

Creare variabili di ambiente

In questo esempio si scriveranno le credenziali nelle variabili di ambiente nel computer locale che esegue l'applicazione.

Vai al portale di Azure. Se le risorse Visione personalizzata create nella sezione Prerequisiti sono state distribuite correttamente, selezionare il pulsante Vai alla risorsa in Passaggi successivi. È possibile trovare le chiavi e gli endpoint nelle pagine chiave ed endpoint delle risorse, in Gestione risorse. È necessario ottenere le chiavi sia per le risorse di training che per le risorse di stima, insieme agli endpoint API.

È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa di stima nella portale di Azure, elencata come ID risorsa.

Suggerimento

È anche possibile usare https://www.customvision.ai/ per ottenere questi valori. Dopo aver eseguito l'accesso, selezionare l'icona Impostazioni in alto a destra. Nelle pagine Impostazione è possibile visualizzare tutte le chiavi, l'ID risorsa e gli endpoint.

Attenzione

Non includere la chiave direttamente nel codice e non pubblicarla pubblicamente. Per altre opzioni di autenticazione come Azure Key Vault, vedere l'articolo sicurezza dei servizi di intelligenza artificiale di Azure.

Per impostare le variabili di ambiente, aprire una finestra della console e seguire le istruzioni per il sistema operativo e l'ambiente di sviluppo.

  1. Per impostare la VISION_TRAINING KEY variabile di ambiente, sostituire your-training-key con una delle chiavi per la risorsa di training.
  2. Per impostare la VISION_TRAINING_ENDPOINT variabile di ambiente, sostituire your-training-endpoint con l'endpoint per la risorsa di training.
  3. Per impostare la VISION_PREDICTION_KEY variabile di ambiente, sostituire your-prediction-key con una delle chiavi per la risorsa di stima.
  4. Per impostare la VISION_PREDICTION_ENDPOINT variabile di ambiente, sostituire your-prediction-endpoint con l'endpoint per la risorsa di stima.
  5. Per impostare la VISION_PREDICTION_RESOURCE_ID variabile di ambiente, sostituire your-resource-id con l'ID risorsa per la risorsa di stima.
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

Dopo aver aggiunto le variabili di ambiente, potrebbe essere necessario riavviare tutti i programmi in esecuzione che leggeranno le variabili di ambiente, inclusa la finestra della console.

Configurazione

Installare la libreria client di Visione personalizzata

Per scrivere un'app di analisi immagini con Visione personalizzata per Go, è necessaria la libreria client di Visione personalizzata. In PowerShell eseguire questo comando:

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

o se si usa dep nell'esecuzione del repository:

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

Ottenere le immagini di esempio

Questo esempio usa le immagini del repository python SDK per i servizi di intelligenza artificiale di Azure in GitHub. Clonare o scaricare questo repository nell'ambiente di sviluppo. Ricordare il percorso della cartella per un passaggio successivo.

Creare il progetto di Visione personalizzata

Creare un nuovo file denominato sample.go nella directory di progetto preferita e aprirlo nell'editor di codice preferito.

Per creare un nuovo progetto di Servizio visione artificiale personalizzato, aggiungere il codice seguente allo script.

Per specificare altre opzioni quando si crea il progetto, come illustrato in Creare un rilevatore nella guida al portale Web, vedere il metodo CreateProject.

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

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

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

    ctx = context.Background()

    trainer := training.New(training_key, endpoint)

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

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

Creare tag nel progetto

Per creare i tag di classificazione per il progetto, aggiungere il codice seguente alla fine del file 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))

Caricare e contrassegnare le immagini

Quando si aggiungono tag alle immagini nei progetti di rilevamento degli oggetti, è necessario specificare l'area di ogni oggetto contrassegnato usando coordinate normalizzate.

Nota

Se non si ha un'utilità di clic e trascinamento per contrassegnare le coordinate delle aree, è possibile usare l'interfaccia utente Web in Customvision.ai. In questo esempio le coordinate sono già disponibili.

Per aggiungere le immagini, i tag e le aree al progetto, inserire il codice seguente dopo la creazione dei tag. Si noti che in questa esercitazione le aree sono hardcoded inline. Le aree specificano il rettangolo delimitatore in coordinate normalizzate e le coordinate sono specificate in questo ordine: sinistra, alto, larghezza, altezza.

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

Usare quindi questa mappa di associazioni per caricare ogni immagine di esempio con le relative coordinate di area. È possibile caricare fino a 64 immagini in un singolo batch. Aggiungi il seguente codice.

Nota

Sarà necessario modificare il percorso delle immagini in base alla posizione in cui è stato scaricato il progetto Go SDK di Azure AI Services Go SDK in precedenza.

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

Eseguire il training del progetto e pubblicarlo

Questo codice crea la prima iterazione del modello di previsione e quindi la pubblica nell'endpoint di previsione. Il nome assegnato all'iterazione pubblicata può essere usato per inviare le richieste di stima. L'iterazione è disponibile nell'endpoint di stima solo dopo che è stata pubblicata.

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

Usare l'endpoint di stima

Per inviare un'immagine all'endpoint di stima e recuperare la stima, aggiungere il codice seguente alla fine del file:

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

Eseguire l'applicazione

Eseguire sample.go.

go run sample.go

L'output dell'applicazione dovrebbe essere visualizzato nella console. È quindi possibile verificare che l'immagine di test (disponibile in samples/vision/images/Test) sia contrassegnata in modo appropriato e che l'area di rilevamento sia corretta.

Pulire le risorse

Se si vuole implementare il proprio progetto di rilevamento degli oggetti (o provare un progetto di classificazione delle immagini), è possibile eliminare il progetto di rilevamento di forchette/forbici da questo esempio. Una sottoscrizione gratuita consente di creare due progetti di Visione personalizzata.

Nel sito Web di Visione personalizzata passare a Projects e selezionare l'icona del cestino sotto My New Project.

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

Passaggi successivi

A questo punto è stato eseguito ogni passaggio del processo di rilevamento degli oggetti nel codice. Questo esempio esegue una sola iterazione del training, ma spesso è necessario eseguire il training e il test del modello più volte per ottenere una maggiore precisione. La guida seguente è incentrata sulla classificazione delle immagini, ma i principi sono simili a quelli del rilevamento di oggetti.

Iniziare a usare la libreria client di Visione personalizzata per Java per creare un modello di rilevamento oggetti. Seguire questi passaggi per installare il pacchetto e provare il codice di esempio per le attività di base. Usare questo esempio come modello per la creazione di un'app di riconoscimento immagini personalizzata.

Nota

Se si intende creare un modello di rilevamento oggetti ed eseguirne il training senza scrivere codice, vedere invece le indicazioni basate sul browser.

Usare la libreria client di Visione personalizzata per Java per:

  • Creare un nuovo progetto Visione personalizzata
  • Aggiungere tag al progetto
  • Caricare e contrassegnare le immagini
  • Eseguire il training del progetto
  • Pubblicare l'iterazione corrente
  • Testare l'endpoint di stima

Documentazione di riferimento | Codice sorgente della libreria (training)(prediction)| Artifact (Maven) (training)(prediction) | Samples

Prerequisiti

Creare variabili di ambiente

In questo esempio si scriveranno le credenziali nelle variabili di ambiente nel computer locale che esegue l'applicazione.

Vai al portale di Azure. Se le risorse Visione personalizzata create nella sezione Prerequisiti sono state distribuite correttamente, selezionare il pulsante Vai alla risorsa in Passaggi successivi. È possibile trovare le chiavi e gli endpoint nelle pagine chiave ed endpoint delle risorse, in Gestione risorse. È necessario ottenere le chiavi sia per le risorse di training che per le risorse di stima, insieme agli endpoint API.

È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa di stima nella portale di Azure, elencata come ID risorsa.

Suggerimento

È anche possibile usare https://www.customvision.ai/ per ottenere questi valori. Dopo aver eseguito l'accesso, selezionare l'icona Impostazioni in alto a destra. Nelle pagine Impostazione è possibile visualizzare tutte le chiavi, l'ID risorsa e gli endpoint.

Attenzione

Non includere la chiave direttamente nel codice e non pubblicarla pubblicamente. Per altre opzioni di autenticazione come Azure Key Vault, vedere l'articolo sicurezza dei servizi di intelligenza artificiale di Azure.

Per impostare le variabili di ambiente, aprire una finestra della console e seguire le istruzioni per il sistema operativo e l'ambiente di sviluppo.

  1. Per impostare la VISION_TRAINING KEY variabile di ambiente, sostituire your-training-key con una delle chiavi per la risorsa di training.
  2. Per impostare la VISION_TRAINING_ENDPOINT variabile di ambiente, sostituire your-training-endpoint con l'endpoint per la risorsa di training.
  3. Per impostare la VISION_PREDICTION_KEY variabile di ambiente, sostituire your-prediction-key con una delle chiavi per la risorsa di stima.
  4. Per impostare la VISION_PREDICTION_ENDPOINT variabile di ambiente, sostituire your-prediction-endpoint con l'endpoint per la risorsa di stima.
  5. Per impostare la VISION_PREDICTION_RESOURCE_ID variabile di ambiente, sostituire your-resource-id con l'ID risorsa per la risorsa di stima.
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

Dopo aver aggiunto le variabili di ambiente, potrebbe essere necessario riavviare tutti i programmi in esecuzione che leggeranno le variabili di ambiente, inclusa la finestra della console.

Configurazione

Creare un nuovo progetto Gradle

In una finestra della console, ad esempio cmd, PowerShell o Bash, creare e passare a una nuova directory per l'app.

mkdir myapp && cd myapp

Eseguire il comando gradle init dalla directory di lavoro. Questo comando creerà i file di compilazione essenziali per Gradle, tra cui build.gradle.kts, che viene usato in fase di esecuzione per creare e configurare l'applicazione.

gradle init --type basic

Quando viene chiesto di scegliere un linguaggio DSL, selezionare Kotlin.

Installare la libreria client

Individuare il file build.gradle.kts e aprirlo con un IDE o un editor di testo a scelta. Quindi copiare la configurazione di compilazione seguente. Questa configurazione definisce il progetto come applicazione Java il cui punto di ingresso è la classe CustomVisionQuickstart. Importa le librerie di Visione personalizzata.

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

Creare un file Java

Dalla directory di lavoro eseguire il comando seguente per creare una cartella di origine del progetto:

mkdir -p src/main/java

Passare alla nuova cartella e creare un file denominato CustomVisionQuickstart.java. Aprirlo in un editor o un IDE a scelta e importare le istruzioni import seguenti:

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;

Suggerimento

Si vuole visualizzare l'intero file di codice dell'argomento di avvio rapido? È possibile trovarlo in GitHub, che contiene gli esempi di codice di questo argomento.

Nella classe CustomVisionQuickstart dell'applicazione creare variabili che recuperano le chiavi e l'endpoint della risorsa dalle variabili di ambiente.

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

Nel metodo main dell'applicazione aggiungere le chiamate per i metodi usati in questa guida di avvio rapido. Verranno definiti in un secondo momento.

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

Modello a oggetti

Le classi e le interfacce seguenti gestiscono alcune delle principali funzionalità della libreria client di Visione personalizzata per Java.

Nome Descrizione
CustomVisionTrainingClient Questa classe gestisce la creazione, il training e la pubblicazione dei modelli.
CustomVisionPredictionClient Questa classe gestisce l'esecuzione di query sui modelli per le previsioni di rilevamento oggetti.
ImagePrediction Questa classe definisce una singola previsione di oggetto in una singola immagine. Include le proprietà per l'ID e il nome dell'oggetto, la posizione del rettangolo di delimitazione dell'oggetto e un punteggio di attendibilità.

Esempi di codice

Questi frammenti di codice mostrano come eseguire le attività seguenti con la libreria client di Visione personalizzata per Java:

Autenticare il client

Nel metodo principale, creare un'istanza dei client di training e di previsione usando l'endpoint e le chiavi.

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

Creare un nuovo progetto Visione personalizzata

Il metodo successivo crea un progetto di rilevamento di oggetti. Il progetto creato verrà visualizzato nel sito Web di Visione personalizzata visitato in precedenza. Per specificare altre opzioni quando si crea il progetto, come illustrato in Creare un rilevatore nella guida al portale Web, vedere gli overload del metodo CreateProject.

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

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

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

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

    return project;
}

Aggiungere i tag al progetto

Questo metodo definisce i tag su cui si eseguirà il training del modello.

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

Caricare e contrassegnare le immagini

Scaricare prima di tutto le immagini di esempio per questo progetto. Salvare il contenuto della cartella immagini di esempio nel dispositivo locale.

Nota

Per completare il training è necessario un set più ampio di immagini? Trove, un progetto Microsoft Garage, consente di raccogliere e acquistare set di immagini a scopo di training. Una volta raccolte le immagini, è possibile scaricarle e quindi importarle nel progetto di Visione personalizzata nel modo consueto. Per altre informazioni, visitare la pagina di Trove.

Quando si aggiungono tag alle immagini nei progetti di rilevamento degli oggetti, è necessario specificare l'area di ogni oggetto contrassegnato usando coordinate normalizzate. Il codice seguente associa ognuna delle immagini di esempio alla relativa area contrassegnata.

Nota

Se non si ha un'utilità di clic e trascinamento per contrassegnare le coordinate delle aree, è possibile usare l'interfaccia utente Web in Customvision.ai. In questo esempio le coordinate sono già disponibili.

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

Il blocco di codice successivo aggiunge le immagini al progetto. È necessario modificare gli argomenti delle chiamate a GetImage in modo che puntino alle posizioni delle cartelle forchetta e forbici scaricate.

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

Il frammento di codice precedente usa due funzioni helper che recuperano le immagini come flussi di risorse e le caricano nel servizio. È possibile caricare fino a 64 immagini in un singolo batch. Definire questi metodi.

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

Eseguire il training del progetto

Questo metodo crea la prima iterazione di training nel progetto. Esegue una query sul servizio fino al completamento del training.

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

Pubblicare l'iterazione corrente

Questo metodo rende disponibile l'iterazione corrente del modello per l'esecuzione di query. È possibile usare il nome del modello come riferimento per inviare richieste di previsione. È necessario immettere il valore corrente per predictionResourceId. È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa nella portale di Azure, elencata come ID risorsa.

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

Testare l'endpoint di stima

Questo metodo carica l'immagine di test, esegue query sull'endpoint del modello e restituisce i dati di stima nella 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()));
    }
}

Eseguire l'applicazione

È possibile compilare l'app con:

gradle build

Eseguire l'applicazione con il comando gradle run:

gradle run

Pulire le risorse

Se si vuole pulire e rimuovere una sottoscrizione dei servizi di intelligenza artificiale di Azure, è possibile eliminare la risorsa o il gruppo di risorse. L'eliminazione del gruppo di risorse comporta anche l'eliminazione di tutte le altre risorse associate.

Se si vuole implementare il proprio progetto di rilevamento degli oggetti (o provare un progetto di classificazione delle immagini), è possibile eliminare il progetto di rilevamento di forchette/forbici da questo esempio. Una sottoscrizione gratuita consente di creare due progetti di Visione personalizzata.

Nel sito Web di Visione personalizzata passare a Projects e selezionare l'icona del cestino sotto My New Project.

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

Passaggi successivi

A questo punto è stato eseguito ogni passaggio del processo di rilevamento degli oggetti nel codice. Questo esempio esegue una sola iterazione del training, ma spesso è necessario eseguire il training e il test del modello più volte per ottenere una maggiore precisione. La guida seguente è incentrata sulla classificazione delle immagini, ma i principi sono simili a quelli del rilevamento di oggetti.

Questa guida fornisce istruzioni e codice di esempio per iniziare a usare la libreria client di Visione personalizzata per Node.js per creare un modello di rilevamento oggetti. Si creerà un progetto, si aggiungeranno tag, si eseguirà il training del progetto e si userà l'URL dell'endpoint di stima del progetto per testarlo a livello di codice. Usare questo esempio come modello per la creazione di un'app di riconoscimento immagini personalizzata.

Nota

Se si intende creare un modello di rilevamento oggetti ed eseguirne il training senza scrivere codice, vedere invece le indicazioni basate sul browser.

Usare la libreria client di Visione personalizzata per .NET per:

  • Creare un nuovo progetto Visione personalizzata
  • Aggiungere tag al progetto
  • Caricare e contrassegnare le immagini
  • Eseguire il training del progetto
  • Pubblicare l'iterazione corrente
  • Testare l'endpoint di stima

Documentazione di riferimento (training)(previsione) | Codice sorgente della libreria (training)(previsione) | Package (npm) (training)(prediction) | Samples

Prerequisiti

Creare variabili di ambiente

In questo esempio si scriveranno le credenziali nelle variabili di ambiente nel computer locale che esegue l'applicazione.

Vai al portale di Azure. Se le risorse Visione personalizzata create nella sezione Prerequisiti sono state distribuite correttamente, selezionare il pulsante Vai alla risorsa in Passaggi successivi. È possibile trovare le chiavi e gli endpoint nelle pagine chiave ed endpoint delle risorse, in Gestione risorse. È necessario ottenere le chiavi sia per le risorse di training che per le risorse di stima, insieme agli endpoint API.

È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa di stima nella portale di Azure, elencata come ID risorsa.

Suggerimento

È anche possibile usare https://www.customvision.ai/ per ottenere questi valori. Dopo aver eseguito l'accesso, selezionare l'icona Impostazioni in alto a destra. Nelle pagine Impostazione è possibile visualizzare tutte le chiavi, l'ID risorsa e gli endpoint.

Attenzione

Non includere la chiave direttamente nel codice e non pubblicarla pubblicamente. Per altre opzioni di autenticazione come Azure Key Vault, vedere l'articolo sicurezza dei servizi di intelligenza artificiale di Azure.

Per impostare le variabili di ambiente, aprire una finestra della console e seguire le istruzioni per il sistema operativo e l'ambiente di sviluppo.

  1. Per impostare la VISION_TRAINING KEY variabile di ambiente, sostituire your-training-key con una delle chiavi per la risorsa di training.
  2. Per impostare la VISION_TRAINING_ENDPOINT variabile di ambiente, sostituire your-training-endpoint con l'endpoint per la risorsa di training.
  3. Per impostare la VISION_PREDICTION_KEY variabile di ambiente, sostituire your-prediction-key con una delle chiavi per la risorsa di stima.
  4. Per impostare la VISION_PREDICTION_ENDPOINT variabile di ambiente, sostituire your-prediction-endpoint con l'endpoint per la risorsa di stima.
  5. Per impostare la VISION_PREDICTION_RESOURCE_ID variabile di ambiente, sostituire your-resource-id con l'ID risorsa per la risorsa di stima.
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

Dopo aver aggiunto le variabili di ambiente, potrebbe essere necessario riavviare tutti i programmi in esecuzione che leggeranno le variabili di ambiente, inclusa la finestra della console.

Configurazione

Creare una nuova applicazione Node.js

In una finestra della console, ad esempio cmd, PowerShell o Bash, creare e passare a una nuova directory per l'app.

mkdir myapp && cd myapp

Eseguire il comando npm init per creare un'applicazione Node con un file package.json.

npm init

Installare la libreria client

Per scrivere un'app di analisi immagini con Visione personalizzata per Node.js, sono necessari i pacchetti npm di Visione personalizzata. Per installarli, eseguire questo comando in PowerShell:

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

Il file package.json dell'app viene aggiornato con le dipendenze.

Creare un file denominato index.js e importare le librerie seguenti:

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

Suggerimento

Si vuole visualizzare l'intero file di codice dell'argomento di avvio rapido? È possibile trovarlo in GitHub, che contiene gli esempi di codice di questo argomento.

Creare le variabili per l'endpoint e le chiavi di Azure della risorsa.

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

Aggiungere anche i campi per il nome del progetto e un parametro di timeout per le chiamate asincrone.

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

Modello a oggetti

Nome Descrizione
TrainingAPIClient Questa classe gestisce la creazione, il training e la pubblicazione dei modelli.
PredictionAPIClient Questa classe gestisce l'esecuzione di query sui modelli per le previsioni di rilevamento oggetti.
Previsione Questa interfaccia definisce una singola previsione in una singola immagine. Include le proprietà per l'ID e il nome dell'oggetto e un punteggio di attendibilità.

Esempi di codice

Questi frammenti di codice mostrano come eseguire le attività seguenti con la libreria client di Visione personalizzata per JavaScript:

Autenticare il client

Creare istanze degli oggetti client con l'endpoint e la chiave. Creare un oggetto ApiKeyCredentials con la chiave e usarlo con l'endpoint per creare gli oggetti TrainingAPIClient e 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);

Aggiungere una funzione helper

Aggiungere la funzione seguente per eseguire più chiamate asincrone. Verrà usata in seguito.

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

Creare un nuovo progetto Visione personalizzata

Avviare una nuova funzione in cui contenere tutte le chiamate di funzione di Visione personalizzata. Aggiungere il codice seguente per creare un nuovo progetto di servizio Visione personalizzata.

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

Aggiungere tag al progetto

Per creare i tag di classificazione per il progetto, aggiungere il codice seguente alla funzione:

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

Caricare e contrassegnare le immagini

Scaricare prima di tutto le immagini di esempio per questo progetto. Salvare il contenuto della cartella immagini di esempio nel dispositivo locale.

Per aggiungere le immagini di esempio al progetto, inserire il codice seguente dopo la creazione dei tag. Questo codice carica ogni immagine con il tag corrispondente. Quando si aggiungono tag alle immagini nei progetti di rilevamento degli oggetti, è necessario specificare l'area di ogni oggetto contrassegnato usando coordinate normalizzate. Per questa esercitazione le aree sono hardcoded in linea con il codice. Le aree specificano il rettangolo delimitatore in coordinate normalizzate e le coordinate sono specificate in questo ordine: sinistra, alto, larghezza, altezza. È possibile caricare fino a 64 immagini in un singolo batch.

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

Importante

È necessario modificare il percorso delle immagini (sampleDataRoot) in base alla posizione in cui è stato scaricato il repository Python SDK samples dei servizi di intelligenza artificiale di Azure.

Nota

Se non si ha un'utilità di clic e trascinamento per contrassegnare le coordinate delle aree, è possibile usare l'interfaccia utente Web in Customvision.ai. In questo esempio le coordinate sono già disponibili.

Eseguire il training del progetto

Questo codice crea la prima iterazione del modello di previsione.

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

Pubblicare l'iterazione corrente

Questo codice pubblica l'iterazione sottoposta a training nell'endpoint di previsione. Il nome assegnato all'iterazione pubblicata può essere usato per inviare le richieste di stima. L'iterazione è disponibile nell'endpoint di stima solo dopo che è stata pubblicata.

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

Testare l'endpoint di stima

Per inviare un'immagine all'endpoint di previsione e recuperare la previsione, aggiungere il codice seguente alla funzione.

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

Chiudere quindi la funzione di Visione personalizzata e chiamarla.

})()

Eseguire l'applicazione

Eseguire l'applicazione con il comando node nel file quickstart.

node index.js

L'output dell'applicazione dovrebbe essere visualizzato nella console. È quindi possibile verificare che l'immagine di test (disponibile in <sampleDataRoot>/Test/) sia contrassegnata in modo appropriato e che l'area di rilevamento sia corretta. È anche possibile tornare al sito Web di Visione personalizzata e vedere lo stato corrente del progetto appena creato.

Pulire le risorse

Se si vuole implementare il proprio progetto di rilevamento degli oggetti (o provare un progetto di classificazione delle immagini), è possibile eliminare il progetto di rilevamento di forchette/forbici da questo esempio. Una sottoscrizione gratuita consente di creare due progetti di Visione personalizzata.

Nel sito Web di Visione personalizzata passare a Projects e selezionare l'icona del cestino sotto My New Project.

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

Passaggi successivi

A questo punto è stato eseguito ogni passaggio del processo di rilevamento degli oggetti nel codice. Questo esempio esegue una sola iterazione del training, ma spesso è necessario eseguire il training e il test del modello più volte per ottenere una maggiore precisione. La guida seguente è incentrata sulla classificazione delle immagini, ma i principi sono simili a quelli del rilevamento di oggetti.

Introduzione alla libreria client di Visione personalizzata per Python. Seguire questi passaggi per installare il pacchetto e provare il codice di esempio per creare un modello di rilevamento oggetti. Si creerà un progetto, si aggiungeranno tag, si eseguirà il training del progetto e si userà l'URL dell'endpoint di stima del progetto per testarlo a livello di codice. Usare questo esempio come modello per la creazione di un'app di riconoscimento immagini personalizzata.

Nota

Se si intende creare un modello di rilevamento oggetti ed eseguirne il training senza scrivere codice, vedere invece le indicazioni basate sul browser.

Usare la libreria client di Visione personalizzata per Python per:

  • Creare un nuovo progetto Visione personalizzata
  • Aggiungere tag al progetto
  • Caricare e contrassegnare le immagini
  • Eseguire il training del progetto
  • Pubblicare l'iterazione corrente
  • Testare l'endpoint di stima

Documentazione di riferimento | Codice sorgente della libreria | Pacchetto (PyPI) | Esempi

Prerequisiti

Creare variabili di ambiente

In questo esempio si scriveranno le credenziali nelle variabili di ambiente nel computer locale che esegue l'applicazione.

Vai al portale di Azure. Se le risorse Visione personalizzata create nella sezione Prerequisiti sono state distribuite correttamente, selezionare il pulsante Vai alla risorsa in Passaggi successivi. È possibile trovare le chiavi e gli endpoint nelle pagine chiave ed endpoint delle risorse, in Gestione risorse. È necessario ottenere le chiavi sia per le risorse di training che per le risorse di stima, insieme agli endpoint API.

È possibile trovare l'ID risorsa di stima nella scheda Proprietà della risorsa di stima nella portale di Azure, elencata come ID risorsa.

Suggerimento

È anche possibile usare https://www.customvision.ai/ per ottenere questi valori. Dopo aver eseguito l'accesso, selezionare l'icona Impostazioni in alto a destra. Nelle pagine Impostazione è possibile visualizzare tutte le chiavi, l'ID risorsa e gli endpoint.

Attenzione

Non includere la chiave direttamente nel codice e non pubblicarla pubblicamente. Per altre opzioni di autenticazione come Azure Key Vault, vedere l'articolo sicurezza dei servizi di intelligenza artificiale di Azure.

Per impostare le variabili di ambiente, aprire una finestra della console e seguire le istruzioni per il sistema operativo e l'ambiente di sviluppo.

  1. Per impostare la VISION_TRAINING KEY variabile di ambiente, sostituire your-training-key con una delle chiavi per la risorsa di training.
  2. Per impostare la VISION_TRAINING_ENDPOINT variabile di ambiente, sostituire your-training-endpoint con l'endpoint per la risorsa di training.
  3. Per impostare la VISION_PREDICTION_KEY variabile di ambiente, sostituire your-prediction-key con una delle chiavi per la risorsa di stima.
  4. Per impostare la VISION_PREDICTION_ENDPOINT variabile di ambiente, sostituire your-prediction-endpoint con l'endpoint per la risorsa di stima.
  5. Per impostare la VISION_PREDICTION_RESOURCE_ID variabile di ambiente, sostituire your-resource-id con l'ID risorsa per la risorsa di stima.
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

Dopo aver aggiunto le variabili di ambiente, potrebbe essere necessario riavviare tutti i programmi in esecuzione che leggeranno le variabili di ambiente, inclusa la finestra della console.

Configurazione

Installare la libreria client

Per scrivere un'app di analisi immagini con Visione personalizzata per Python, è necessaria la libreria client di Visione personalizzata. Dopo l'installazione di Python, eseguire il comando seguente in PowerShell o in una finestra della console:

pip install azure-cognitiveservices-vision-customvision

Creare una nuova applicazione Python

Creare un nuovo file Python e importare le librerie seguenti.

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

Suggerimento

Si vuole visualizzare l'intero file di codice dell'argomento di avvio rapido? È possibile trovarlo in GitHub, che contiene gli esempi di codice di questo argomento.

Creare le variabili per l'endpoint e le chiavi di Azure della risorsa.

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

Modello a oggetti

Nome Descrizione
CustomVisionTrainingClient Questa classe gestisce la creazione, il training e la pubblicazione dei modelli.
CustomVisionPredictionClient Questa classe gestisce l'esecuzione di query sui modelli per le previsioni di rilevamento oggetti.
ImagePrediction Questa classe definisce una singola previsione di oggetto in una singola immagine. Include le proprietà per l'ID e il nome dell'oggetto, la posizione del rettangolo di delimitazione dell'oggetto e un punteggio di attendibilità.

Esempi di codice

Questi frammenti di codice mostrano come eseguire le attività seguenti con la libreria client di Visione personalizzata per Python:

Autenticare il client

Creare un'istanza dei client di training e di previsione con l'endpoint e le chiavi. Creare oggetti ApiKeyServiceClientCredentials con le chiavi e usarli con l'endpoint per creare un oggetto CustomVisionTrainingClient e CustomVisionPredictionClient.

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

Creare un nuovo progetto Visione personalizzata

Per creare un nuovo progetto di Servizio visione artificiale personalizzato, aggiungere il codice seguente allo script.

Per specificare altre opzioni quando si crea il progetto, come illustrato nella guida del portale Web Creare un rilevatore, vedere il metodo create_project.

publish_iteration_name = "detectModel"

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

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

Aggiungere tag al progetto

Per creare i tag degli oggetti nel progetto, aggiungere il codice seguente:

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

Caricare e contrassegnare le immagini

Scaricare prima di tutto le immagini di esempio per questo progetto. Salvare il contenuto della cartella immagini di esempio nel dispositivo locale.

Quando si aggiungono tag alle immagini nei progetti di rilevamento degli oggetti, è necessario specificare l'area di ogni oggetto contrassegnato usando coordinate normalizzate. Il codice seguente associa ognuna delle immagini di esempio alla relativa area contrassegnata. Le aree specificano il rettangolo delimitatore in coordinate normalizzate e le coordinate sono specificate in questo ordine: sinistra, alto, larghezza, altezza.

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

Nota

Se non si ha un'utilità di clic e trascinamento per contrassegnare le coordinate delle aree, è possibile usare l'interfaccia utente Web in Customvision.ai. In questo esempio le coordinate sono già disponibili.

Usare quindi questa mappa di associazioni per caricare ogni immagine di esempio con le relative coordinate di area. È possibile caricare fino a 64 immagini in un singolo batch. Aggiungi il seguente codice.

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)

Nota

Sarà necessario modificare il percorso delle immagini in base alla posizione in cui è stato scaricato il repository di esempi di Python SDK per i servizi di intelligenza artificiale di Azure in precedenza.

Eseguire il training del progetto

Questo codice crea la prima iterazione del modello di previsione.

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)

Suggerimento

Eseguire il training con i tag selezionati

Facoltativamente, è possibile eseguire il training solo su un subset dei tag applicati. Questa operazione può essere eseguita se non è ancora stato applicato un numero sufficiente di determinati tag, ma si dispone di un numero sufficiente di altri. Nella chiamata train_project impostare il parametro opzionale selected_tags su un elenco di stringhe di ID dei tag da usare. Il modello eseguirà il training in modo da riconoscere solo i tag nell'elenco.

Pubblicare l'iterazione corrente

L'iterazione è disponibile nell'endpoint di stima solo dopo che è stata pubblicata. Il codice seguente rende disponibile l'iterazione corrente del modello per l'esecuzione di query.

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

Testare l'endpoint di stima

Per inviare un'immagine all'endpoint di stima e recuperare la stima, aggiungere il codice seguente alla fine del file:

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

Eseguire l'applicazione

Eseguire CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

L'output dell'applicazione dovrebbe essere visualizzato nella console. È quindi possibile verificare che l'immagine di test (disponibile in <base_image_location>/images/Test) sia contrassegnata in modo appropriato e che l'area di rilevamento sia corretta. È anche possibile tornare al sito Web di Visione personalizzata e vedere lo stato corrente del progetto appena creato.

Pulire le risorse

Se si vuole implementare il proprio progetto di rilevamento degli oggetti (o provare un progetto di classificazione delle immagini), è possibile eliminare il progetto di rilevamento di forchette/forbici da questo esempio. Una sottoscrizione gratuita consente di creare due progetti di Visione personalizzata.

Nel sito Web di Visione personalizzata passare a Projects e selezionare l'icona del cestino sotto My New Project.

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

Passaggi successivi

A questo punto è stato eseguito ogni passaggio del processo di rilevamento degli oggetti nel codice. Questo esempio esegue una sola iterazione del training, ma spesso è necessario eseguire il training e il test del modello più volte per ottenere una maggiore precisione. La guida seguente è incentrata sulla classificazione delle immagini, ma i principi sono simili a quelli del rilevamento di oggetti.