Guia de início rápido: criar um projeto de deteção de objetos com a biblioteca de cliente do Custom Vision

Introdução à biblioteca de cliente Custom Vision para .NET. Siga estas etapas para instalar o pacote e experimentar o código de exemplo para criar um modelo de deteção de objeto. Você criará um projeto, adicionará tags, treinará o projeto em imagens de exemplo e usará a URL do ponto de extremidade de previsão do projeto para testá-lo programaticamente. Use este exemplo como um modelo para criar seu próprio aplicativo de reconhecimento de imagem.

Nota

Se você quiser criar e treinar um modelo de deteção de objetos sem escrever código, consulte as diretrizes baseadas em navegador.

Documentação de referência | Código fonte da biblioteca (formação)(previsão) | Pacote (NuGet) (treinamento)(previsão) | Amostras

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará suas credenciais em variáveis de ambiente na máquina local que executa o aplicativo.

Aceda ao portal do Azure. Se os recursos da Visão Personalizada criados na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para o recurso em Próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas de chaves e pontos finais dos recursos, em Gerenciamento de recursos. Você precisará obter as chaves para seus recursos de treinamento e previsão, juntamente com os pontos de extremidade da API.

Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Gorjeta

Você também usa https://www.customvision.ai/ para obter esses valores. Depois de iniciar sessão, selecione o ícone Definições no canto superior direito. Nas páginas Configuração, você pode exibir todas as chaves, ID do recurso e pontos de extremidade.

Atenção

Não inclua a chave diretamente no seu código e nunca a publique publicamente. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais opções de autenticação, como o Azure Key Vault.

Para definir as variáveis de ambiente, abra uma janela de console e siga as instruções para seu sistema operacional e ambiente de desenvolvimento.

  1. Para definir a VISION_TRAINING KEY variável de ambiente, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua your-training-endpoint pelo ponto de extremidade do seu recurso de treinamento.
  3. Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a VISION_PREDICTION_ENDPOINT variável de ambiente, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a VISION_PREDICTION_RESOURCE_ID variável de ambiente, substitua your-resource-id pelo ID do recurso de previsão.
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

Depois de adicionar as variáveis de ambiente, talvez seja necessário reiniciar todos os programas em execução que lerão as variáveis de ambiente, incluindo a janela do console.

Configuração

Criar um novo aplicativo C#

Usando o Visual Studio, crie um novo aplicativo .NET Core.

Instalar a biblioteca de cliente

Depois de criar um novo projeto, instale a biblioteca de cliente clicando com o botão direito do mouse na solução do projeto no Gerenciador de Soluções e selecionando Gerenciar Pacotes NuGet. No gerenciador de pacotes aberto, selecione Procurar, marque Incluir pré-lançamento e procure Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training e Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Selecione a versão mais recente e, em seguida, Instalar.

Gorjeta

Quer ver todo o ficheiro de código do início rápido de uma vez? Pode encontrá-lo no GitHub, que contém os exemplos de código deste início rápido.

No diretório do projeto, abra o arquivo .cs programa e adicione as seguintes using diretivas:

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;

No método Main do aplicativo, crie variáveis que recuperem as chaves e o ponto de extremidade do recurso a partir de variáveis de ambiente. Você também declarará alguns objetos básicos a serem usados posteriormente.

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

No método Main do aplicativo, adicione chamadas para os métodos usados neste início rápido. Você irá implementá-los mais tarde.

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

Autenticar o cliente

Em um novo método, instancie clientes de treinamento e previsão usando seu endpoint e chaves.

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

Criar um novo projeto de Visão Personalizada

Este próximo método cria um projeto de deteção de objeto. O projeto criado aparecerá no site da Visão Personalizada. Consulte o método CreateProject para especificar outras opções ao criar seu projeto (explicado no guia do portal da Web Build a detetor ).

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

Adicionar etiquetas ao projeto

Esse método define as tags nas quais você treinará o modelo.

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

Carregar e etiquetar imagens

Primeiro, faça o download das imagens de exemplo para este projeto. Salve o conteúdo da pasta Imagens de exemplo em seu dispositivo local.

Ao etiquetar imagens em projetos de deteção de objeto, tem de especificar a região de cada objeto etiquetado com coordenadas normalizadas. O código seguinte associa cada uma das imagens de exemplo à respetiva região marcada.

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

Para seus próprios projetos, se você não tiver um utilitário de clicar e arrastar para marcar as coordenadas das regiões, poderá usar a interface do usuário da Web no site da Visão Personalizada. Neste exemplo, as coordenadas já são fornecidas.

Depois, utilize este mapa de associações para carregar cada imagem de exemplo com as respetivas coordenadas de região. Pode carregar até 64 imagens num único lote. Talvez seja necessário alterar o imagePath valor para apontar para os locais de pasta corretos.

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

Neste ponto, você carregou todas as imagens de amostras e marcou cada uma delas (garfo ou tesoura) com um retângulo de pixel associado.

Preparar o projeto

Esse método cria a primeira iteração de treinamento no projeto. Ele consulta o serviço até que o treinamento seja concluído.

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

Gorjeta

Treinar com tags selecionadas

Opcionalmente, você pode treinar apenas em um subconjunto de suas tags aplicadas. Você pode querer fazer isso se ainda não aplicou o suficiente de certas tags, mas você tem o suficiente de outras. Na chamada TrainProject, use o parâmetro trainingParameters. Construa um TrainingParameters e defina sua propriedade SelectedTags como uma lista de IDs das tags que você deseja usar. O modelo treinará para reconhecer apenas as tags nessa lista.

Publicar a iteração atual

Esse método torna a iteração atual do modelo disponível para consulta. Você pode usar o nome do modelo como referência para enviar solicitações de previsão. Você precisa inserir seu próprio valor para predictionResourceId. Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso no portal do Azure, listada como ID do Recurso.

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

Testar o ponto de extremidade de previsão

Esse método carrega a imagem de teste, consulta o ponto de extremidade do modelo e gera dados de previsão para o 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();
}

Executar a aplicação

Execute o aplicativo clicando no botão Depurar na parte superior da janela do IDE.

À medida que a aplicação é executada, deverá abrir uma janela e consola e escrever a saída seguinte:

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 ]

Depois, pode confirmar se a imagem de teste (que está em Images/Test/) está identificada corretamente e se a região de deteção é a certa. Nesta fase, pode premir qualquer tecla para sair da aplicação.

Clean up resources (Limpar recursos)

Se desejar implementar o seu próprio projeto de deteção de objetos (ou, em vez disso, experimentar um projeto de classificação de imagens), deve eliminar o projeto de deteção de bifurcação/tesouras deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No Site de Visão Personalizada, navegue para Projetos e selecione o caixote do lixo em O Meu Novo Projeto.

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

Próximos passos

Agora você fez todas as etapas do processo de deteção de objetos no código. Este exemplo executa uma única iteração de treinamento, mas muitas vezes você precisará treinar e testar seu modelo várias vezes para torná-lo mais preciso. O guia seguinte aborda a classificação de imagens, mas os seus princípios são semelhantes à deteção de objetos.

Test and retrain a model (Testar e voltar a preparar um modelo)

Este guia fornece instruções e código de exemplo para ajudá-lo a começar a usar a biblioteca de cliente Custom Vision for Go para criar um modelo de deteção de objeto. Você criará um projeto, adicionará tags, treinará o projeto e usará a URL do ponto de extremidade de previsão do projeto para testá-lo programaticamente. Use este exemplo como um modelo para criar seu próprio aplicativo de reconhecimento de imagem.

Nota

Se você quiser criar e treinar um modelo de deteção de objetos sem escrever código, consulte as diretrizes baseadas em navegador.

Use a biblioteca de cliente da Visão Personalizada para Ir para:

  • Criar um novo projeto de Visão Personalizada
  • Adicionar etiquetas ao projeto
  • Carregar e etiquetar imagens
  • Preparar o projeto
  • Publicar a iteração atual
  • Testar o ponto de extremidade de previsão

Documentação de referência (formação) (previsão)

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará suas credenciais em variáveis de ambiente na máquina local que executa o aplicativo.

Aceda ao portal do Azure. Se os recursos da Visão Personalizada criados na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para o recurso em Próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas de chaves e pontos finais dos recursos, em Gerenciamento de recursos. Você precisará obter as chaves para seus recursos de treinamento e previsão, juntamente com os pontos de extremidade da API.

Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Gorjeta

Você também usa https://www.customvision.ai/ para obter esses valores. Depois de iniciar sessão, selecione o ícone Definições no canto superior direito. Nas páginas Configuração, você pode exibir todas as chaves, ID do recurso e pontos de extremidade.

Atenção

Não inclua a chave diretamente no seu código e nunca a publique publicamente. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais opções de autenticação, como o Azure Key Vault.

Para definir as variáveis de ambiente, abra uma janela de console e siga as instruções para seu sistema operacional e ambiente de desenvolvimento.

  1. Para definir a VISION_TRAINING KEY variável de ambiente, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua your-training-endpoint pelo ponto de extremidade do seu recurso de treinamento.
  3. Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a VISION_PREDICTION_ENDPOINT variável de ambiente, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a VISION_PREDICTION_RESOURCE_ID variável de ambiente, substitua your-resource-id pelo ID do recurso de previsão.
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

Depois de adicionar as variáveis de ambiente, talvez seja necessário reiniciar todos os programas em execução que lerão as variáveis de ambiente, incluindo a janela do console.

Configuração

Instalar a biblioteca de cliente do Custom Vision

Para escrever um aplicativo de análise de imagem com o Custom Vision for Go, você precisará da biblioteca de cliente do serviço Custom Vision. Execute o seguinte comando no PowerShell:

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

ou se você usar depo , dentro da sua execução de recompra:

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

Obter imagens de amostra

Este exemplo usa as imagens do repositório de exemplos do SDK do Python dos serviços de IA do Azure no GitHub. Clone ou transfira este repositório para o seu ambiente de desenvolvimento. Lembre-se do local da pasta para uma etapa posterior.

Criar o projeto Visão Personalizada

Crie um novo arquivo chamado sample.go em seu diretório de projeto preferido e abra-o em seu editor de código preferido.

Adicione o código seguinte ao seu script para criar um novo projeto do serviço de Visão Personalizada.

Consulte o método CreateProject para especificar outras opções ao criar seu projeto (explicado no guia do portal da Web Build a detetor ).

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

Criar etiquetas no projeto

Para criar marcas de classificação ao seu projeto, adicione o seguinte código ao final 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))

Carregar e etiquetar imagens

Ao etiquetar imagens em projetos de deteção de objeto, tem de especificar a região de cada objeto etiquetado com coordenadas normalizadas.

Nota

Se você não tiver um utilitário de clicar e arrastar para marcar as coordenadas das regiões, poderá usar a interface do usuário da Web em Customvision.ai. Neste exemplo, as coordenadas já são fornecidas.

Para adicionar as imagens, etiquetas e regiões ao projeto, insira o seguinte código após a criação da etiqueta. Observe que, neste tutorial, as regiões são codificadas em linha. As regiões especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são dadas pela ordem seguinte: esquerda, superior, largura, altura.

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

Em seguida, use este mapa de associações para carregar cada imagem de exemplo com suas coordenadas de região (você pode carregar até 64 imagens em um único lote). Adicione o seguinte código.

Nota

Você precisará alterar o caminho para as imagens com base em onde você baixou o projeto Azure AI services Go SDK Samples anteriormente.

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

Treinar e publicar o projeto

Esse código cria a primeira iteração do modelo de previsão e, em seguida, publica essa iteração no ponto de extremidade de previsão. O nome dado à iteração publicada pode ser usado para enviar solicitações de previsão. Uma iteração não está disponível no ponto de extremidade de previsão até que seja publicada.

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

Utilizar o ponto final de predição

Para enviar uma imagem para o ponto final de predição e obter a mesma, adicione o seguinte código no fim do ficheiro:

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

Executar a aplicação

Execute sample.go.

go run sample.go

A saída da aplicação deverá aparecer na consola. Pode, em seguida, certificar-se de que a imagem de teste (encontrada em amostras/visão/imagens/Teste) está identificada de forma adequada e que a região de deteção está correta.

Clean up resources (Limpar recursos)

Se desejar implementar o seu próprio projeto de deteção de objetos (ou, em vez disso, experimentar um projeto de classificação de imagens), deve eliminar o projeto de deteção de bifurcação/tesouras deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No Site de Visão Personalizada, navegue para Projetos e selecione o caixote do lixo em O Meu Novo Projeto.

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

Próximos passos

Agora você fez todas as etapas do processo de deteção de objetos no código. Este exemplo executa uma única iteração de treinamento, mas muitas vezes você precisará treinar e testar seu modelo várias vezes para torná-lo mais preciso. O guia seguinte aborda a classificação de imagens, mas os seus princípios são semelhantes à deteção de objetos.

Test and retrain a model (Testar e voltar a preparar um modelo)

Comece a usar a biblioteca de cliente Custom Vision para Java para criar um modelo de deteção de objetos. Siga estas etapas para instalar o pacote e experimentar o código de exemplo para tarefas básicas. Use este exemplo como um modelo para criar seu próprio aplicativo de reconhecimento de imagem.

Nota

Se você quiser criar e treinar um modelo de deteção de objetos sem escrever código, consulte as diretrizes baseadas em navegador.

Use a biblioteca de cliente Custom Vision para Java para:

  • Criar um novo projeto de Visão Personalizada
  • Adicionar etiquetas ao projeto
  • Carregar e etiquetar imagens
  • Preparar o projeto
  • Publicar a iteração atual
  • Testar o ponto de extremidade de previsão

Documentação de referência | Código fonte da biblioteca (formação)(previsão)| Artefato (Maven) (treinamento)(previsão) | Amostras

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará suas credenciais em variáveis de ambiente na máquina local que executa o aplicativo.

Aceda ao portal do Azure. Se os recursos da Visão Personalizada criados na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para o recurso em Próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas de chaves e pontos finais dos recursos, em Gerenciamento de recursos. Você precisará obter as chaves para seus recursos de treinamento e previsão, juntamente com os pontos de extremidade da API.

Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Gorjeta

Você também usa https://www.customvision.ai/ para obter esses valores. Depois de iniciar sessão, selecione o ícone Definições no canto superior direito. Nas páginas Configuração, você pode exibir todas as chaves, ID do recurso e pontos de extremidade.

Atenção

Não inclua a chave diretamente no seu código e nunca a publique publicamente. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais opções de autenticação, como o Azure Key Vault.

Para definir as variáveis de ambiente, abra uma janela de console e siga as instruções para seu sistema operacional e ambiente de desenvolvimento.

  1. Para definir a VISION_TRAINING KEY variável de ambiente, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua your-training-endpoint pelo ponto de extremidade do seu recurso de treinamento.
  3. Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a VISION_PREDICTION_ENDPOINT variável de ambiente, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a VISION_PREDICTION_RESOURCE_ID variável de ambiente, substitua your-resource-id pelo ID do recurso de previsão.
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

Depois de adicionar as variáveis de ambiente, talvez seja necessário reiniciar todos os programas em execução que lerão as variáveis de ambiente, incluindo a janela do console.

Configuração

Criar um novo projeto Gradle

Numa janela de consola (como cmd, PowerShell ou Bash), crie um novo diretório para a sua aplicação e navegue para a mesma.

mkdir myapp && cd myapp

Execute o comando a gradle init partir do seu diretório de trabalho. Este comando criará arquivos de compilação essenciais para o Gradle, incluindo build.gradle.kts, que é usado em tempo de execução para criar e configurar seu aplicativo.

gradle init --type basic

Quando solicitado a escolher uma DSL, selecione Kotlin.

Instalar a biblioteca de cliente

Localize build.gradle.kts e abra-o com o seu IDE ou editor de texto preferido. Em seguida, copie na seguinte configuração de compilação. Esta configuração define o projeto como uma aplicação Java cujo ponto de entrada é a classe CustomVisionQuickstart. Ele importa as bibliotecas de Visão Personalizada.

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

Criar um arquivo Java

No diretório de trabalho, execute o seguinte comando para criar uma pasta de origem do projeto:

mkdir -p src/main/java

Navegue até a nova pasta e crie um arquivo chamado CustomVisionQuickstart.java. Abra-o em seu editor ou IDE preferido e adicione as seguintes import instruções:

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;

Gorjeta

Quer ver todo o ficheiro de código do início rápido de uma vez? Pode encontrá-lo no GitHub, que contém os exemplos de código deste início rápido.

Na classe CustomVisionQuickstart do aplicativo, crie variáveis que recuperem as chaves e o ponto de extremidade do recurso a partir de variáveis de 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");

No método principal do aplicativo, adicione chamadas para os métodos usados neste início rápido. Você os definirá mais tarde.

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

Modelo de objeto

As classes e interfaces a seguir lidam com alguns dos principais recursos da biblioteca de cliente Java Custom Vision.

Nome Descrição
CustomVisionTrainingClient Esta classe lida com a criação, treinamento e publicação de seus modelos.
CustomVisionPredictionClient Essa classe lida com a consulta de seus modelos para previsões de deteção de objetos.
ImagePrediction Essa classe define uma previsão de objeto único em uma única imagem. Ele inclui propriedades para o ID e o nome do objeto, o local da caixa delimitadora do objeto e uma pontuação de confiança.

Exemplos de código

Esses trechos de código mostram como executar as seguintes tarefas com a biblioteca de cliente Custom Vision para Java:

Autenticar o cliente

Em seu método principal, instancie clientes de treinamento e previsão usando seu endpoint e chaves.

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

Criar um novo projeto de Visão Personalizada

Este próximo método cria um projeto de deteção de objeto. O projeto criado aparece no site da Visão Personalizada ao qual acedeu anteriormente. Consulte as sobrecargas do método CreateProject para especificar outras opções ao criar seu projeto (explicado no guia do portal da Web Criar um detetor).

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

Adicionar etiquetas ao seu projeto

Esse método define as tags nas quais você treinará o modelo.

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

Carregar e etiquetar imagens

Primeiro, faça o download das imagens de exemplo para este projeto. Salve o conteúdo da pasta Imagens de exemplo em seu dispositivo local.

Nota

Precisa de um conjunto mais amplo de imagens para completar a sua formação? Trove, um projeto do Microsoft Garage, permite que você colete e compre conjuntos de imagens para fins de treinamento. Depois de coletar suas imagens, você pode baixá-las e, em seguida, importá-las para seu projeto Visão Personalizada da maneira usual. Visite a página do Trove para saber mais.

Ao etiquetar imagens em projetos de deteção de objeto, tem de especificar a região de cada objeto etiquetado com coordenadas normalizadas. O código seguinte associa cada uma das imagens de exemplo à respetiva região marcada.

Nota

Se você não tiver um utilitário de clicar e arrastar para marcar as coordenadas das regiões, poderá usar a interface do usuário da Web em Customvision.ai. Neste exemplo, as coordenadas já são fornecidas.

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

O próximo bloco de código adiciona as imagens ao projeto. Você precisará alterar os GetImage argumentos das chamadas para apontar para os locais das pastas de garfo e tesoura que você baixou.

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

O trecho de código anterior faz uso de duas funções auxiliares que recuperam as imagens como fluxos de recursos e as carregam para o serviço (você pode carregar até 64 imagens em um único lote). Defina esses métodos.

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

Preparar o projeto

Esse método cria a primeira iteração de treinamento no projeto. Ele consulta o serviço até que o treinamento seja concluído.

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

Publicar a iteração atual

Esse método torna a iteração atual do modelo disponível para consulta. Você pode usar o nome do modelo como referência para enviar solicitações de previsão. Você precisa inserir seu próprio valor para predictionResourceId. Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso no portal do Azure, listada como ID do Recurso.

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

Testar o ponto de extremidade de previsão

Esse método carrega a imagem de teste, consulta o ponto de extremidade do modelo e gera dados de previsão para o 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()));
    }
}

Executar a aplicação

Você pode criar o aplicativo com:

gradle build

Execute o aplicativo com o gradle run comando:

gradle run

Clean up resources (Limpar recursos)

Se quiser limpar e remover uma assinatura de serviços do Azure AI, você pode excluir o recurso ou grupo de recursos. A exclusão do grupo de recursos também exclui quaisquer outros recursos associados a ele.

Se desejar implementar o seu próprio projeto de deteção de objetos (ou, em vez disso, experimentar um projeto de classificação de imagens), deve eliminar o projeto de deteção de bifurcação/tesouras deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No Site de Visão Personalizada, navegue para Projetos e selecione o caixote do lixo em O Meu Novo Projeto.

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

Próximos passos

Agora você fez todas as etapas do processo de deteção de objetos no código. Este exemplo executa uma única iteração de treinamento, mas muitas vezes você precisará treinar e testar seu modelo várias vezes para torná-lo mais preciso. O guia seguinte aborda a classificação de imagens, mas os seus princípios são semelhantes à deteção de objetos.

Test and retrain a model (Testar e voltar a preparar um modelo)

Este guia fornece instruções e código de exemplo para ajudá-lo a começar a usar a biblioteca de cliente Custom Vision para Node.js para criar um modelo de deteção de objeto. Você criará um projeto, adicionará tags, treinará o projeto e usará a URL do ponto de extremidade de previsão do projeto para testá-lo programaticamente. Use este exemplo como um modelo para criar seu próprio aplicativo de reconhecimento de imagem.

Nota

Se você quiser criar e treinar um modelo de deteção de objetos sem escrever código, consulte as diretrizes baseadas em navegador.

Use a biblioteca de cliente Custom Vision para .NET para:

  • Criar um novo projeto de Visão Personalizada
  • Adicionar etiquetas ao projeto
  • Carregar e etiquetar imagens
  • Preparar o projeto
  • Publicar a iteração atual
  • Testar o ponto de extremidade de previsão

Documentação de referência (formação)(previsão) | Código fonte da biblioteca (formação)(previsão) | Pacote (npm) (treinamento)(previsão) | Amostras

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará suas credenciais em variáveis de ambiente na máquina local que executa o aplicativo.

Aceda ao portal do Azure. Se os recursos da Visão Personalizada criados na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para o recurso em Próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas de chaves e pontos finais dos recursos, em Gerenciamento de recursos. Você precisará obter as chaves para seus recursos de treinamento e previsão, juntamente com os pontos de extremidade da API.

Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Gorjeta

Você também usa https://www.customvision.ai/ para obter esses valores. Depois de iniciar sessão, selecione o ícone Definições no canto superior direito. Nas páginas Configuração, você pode exibir todas as chaves, ID do recurso e pontos de extremidade.

Atenção

Não inclua a chave diretamente no seu código e nunca a publique publicamente. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais opções de autenticação, como o Azure Key Vault.

Para definir as variáveis de ambiente, abra uma janela de console e siga as instruções para seu sistema operacional e ambiente de desenvolvimento.

  1. Para definir a VISION_TRAINING KEY variável de ambiente, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua your-training-endpoint pelo ponto de extremidade do seu recurso de treinamento.
  3. Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a VISION_PREDICTION_ENDPOINT variável de ambiente, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a VISION_PREDICTION_RESOURCE_ID variável de ambiente, substitua your-resource-id pelo ID do recurso de previsão.
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

Depois de adicionar as variáveis de ambiente, talvez seja necessário reiniciar todos os programas em execução que lerão as variáveis de ambiente, incluindo a janela do console.

Configuração

Criar uma nova aplicação Node.js

Numa janela de consola (como cmd, PowerShell ou Bash), crie um novo diretório para a sua aplicação e navegue para a mesma.

mkdir myapp && cd myapp

Execute o comando npm init para criar uma aplicação de nó com um ficheiro package.json.

npm init

Instalar a biblioteca de cliente

Para escrever um aplicativo de análise de imagem com o Custom Vision for Node.js, você precisará dos pacotes Custom Vision NPM. Para instalá-los, execute o seguinte comando no PowerShell:

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

O ficheiro package.json da sua aplicação será atualizado com as dependências.

Crie um arquivo chamado index.js e importe as seguintes bibliotecas:

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

Gorjeta

Quer ver todo o ficheiro de código do início rápido de uma vez? Pode encontrá-lo no GitHub, que contém os exemplos de código deste início rápido.

Crie variáveis para o ponto de extremidade e as chaves do Azure do seu recurso.

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

Adicione também campos para o nome do projeto e um parâmetro de tempo limite para chamadas assíncronas.

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

Modelo de objeto

Nome Descrição
FormaçãoAPIClient Esta classe lida com a criação, treinamento e publicação de seus modelos.
PrevisãoAPIClient Essa classe lida com a consulta de seus modelos para previsões de deteção de objetos.
Predição Essa interface define uma única previsão em uma única imagem. Inclui propriedades para o ID e o nome do objeto e uma pontuação de confiança.

Exemplos de código

Esses trechos de código mostram como executar as seguintes tarefas com a biblioteca de cliente Custom Vision para JavaScript:

Autenticar o cliente

Instancie objetos de cliente com seu ponto de extremidade e chave. Crie um objeto ApiKeyCredentials com sua chave e use-o com seu ponto de extremidade para criar um objeto 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);

Adicionar função auxiliar

Adicione a seguinte função para ajudar a fazer várias chamadas assíncronas. Você usará isso mais tarde.

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

Criar um novo projeto de Visão Personalizada

Inicie uma nova função para conter todas as suas chamadas de função Visão Personalizada. Adicione o seguinte código para criar um novo projeto de serviço de Visão Personalizada.

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

Adicionar etiquetas ao projeto

Para criar tags de classificação ao seu projeto, adicione o seguinte código à sua função:

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

Carregar e etiquetar imagens

Primeiro, faça o download das imagens de exemplo para este projeto. Salve o conteúdo da pasta Imagens de exemplo em seu dispositivo local.

Para adicionar as imagens de exemplo ao projeto, insira o seguinte código após a criação da etiqueta. Este código carrega cada imagem com a etiqueta correspondente. Ao etiquetar imagens em projetos de deteção de objeto, tem de especificar a região de cada objeto etiquetado com coordenadas normalizadas. Para este tutorial, as regiões são codificadas em linha com o código. As regiões especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são dadas pela ordem seguinte: esquerda, superior, largura, altura. Pode carregar até 64 imagens num único lote.

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

Você precisará alterar o caminho para as imagens (sampleDataRoot) com base em onde você baixou o repositório Exemplos do SDK do Python dos serviços de IA do Azure.

Nota

Se você não tiver um utilitário de clicar e arrastar para marcar as coordenadas das regiões, poderá usar a interface do usuário da Web em Customvision.ai. Neste exemplo, as coordenadas já são fornecidas.

Preparar o projeto

Este código cria a primeira iteração do modelo de previsão.

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

Publicar a iteração atual

Este código publica a iteração treinada para o ponto de extremidade de previsão. O nome dado à iteração publicada pode ser usado para enviar solicitações de previsão. Uma iteração não está disponível no ponto de extremidade de previsão até que seja publicada.

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

Testar o ponto de extremidade de previsão

Para enviar uma imagem para o ponto de extremidade de previsão e recuperar a previsão, adicione o seguinte código à sua função.

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

Em seguida, feche a função Visão Personalizada e chame-a.

})()

Executar a aplicação

Execute a aplicação com o comando node no seu ficheiro de início rápido.

node index.js

A saída da aplicação deverá aparecer na consola. Em seguida, você pode verificar se a imagem de teste (encontrada em <sampleDataRoot>/Test/) está marcada adequadamente e se a região de deteção está correta. Também pode regressar ao site da Visão Personalizada e ver o estado atual do projeto criado recentemente.

Clean up resources (Limpar recursos)

Se desejar implementar o seu próprio projeto de deteção de objetos (ou, em vez disso, experimentar um projeto de classificação de imagens), deve eliminar o projeto de deteção de bifurcação/tesouras deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No Site de Visão Personalizada, navegue para Projetos e selecione o caixote do lixo em O Meu Novo Projeto.

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

Próximos passos

Agora você fez todas as etapas do processo de deteção de objetos no código. Este exemplo executa uma única iteração de treinamento, mas muitas vezes você precisará treinar e testar seu modelo várias vezes para torná-lo mais preciso. O guia seguinte aborda a classificação de imagens, mas os seus princípios são semelhantes à deteção de objetos.

Test and retrain a model (Testar e voltar a preparar um modelo)

Introdução à biblioteca de cliente Custom Vision para Python. Siga estas etapas para instalar o pacote e experimentar o código de exemplo para criar um modelo de deteção de objeto. Você criará um projeto, adicionará tags, treinará o projeto e usará a URL do ponto de extremidade de previsão do projeto para testá-lo programaticamente. Use este exemplo como um modelo para criar seu próprio aplicativo de reconhecimento de imagem.

Nota

Se você quiser criar e treinar um modelo de deteção de objetos sem escrever código, consulte as diretrizes baseadas em navegador.

Use a biblioteca de cliente Custom Vision para Python para:

  • Criar um novo projeto de Visão Personalizada
  • Adicionar etiquetas ao projeto
  • Carregar e etiquetar imagens
  • Preparar o projeto
  • Publicar a iteração atual
  • Testar o ponto de extremidade de previsão

Documentação | de referência Pacote de código-fonte | da biblioteca (PyPI)Amostras |

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará suas credenciais em variáveis de ambiente na máquina local que executa o aplicativo.

Aceda ao portal do Azure. Se os recursos da Visão Personalizada criados na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para o recurso em Próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas de chaves e pontos finais dos recursos, em Gerenciamento de recursos. Você precisará obter as chaves para seus recursos de treinamento e previsão, juntamente com os pontos de extremidade da API.

Você pode encontrar a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Gorjeta

Você também usa https://www.customvision.ai/ para obter esses valores. Depois de iniciar sessão, selecione o ícone Definições no canto superior direito. Nas páginas Configuração, você pode exibir todas as chaves, ID do recurso e pontos de extremidade.

Atenção

Não inclua a chave diretamente no seu código e nunca a publique publicamente. Consulte o artigo de segurança dos serviços de IA do Azure para obter mais opções de autenticação, como o Azure Key Vault.

Para definir as variáveis de ambiente, abra uma janela de console e siga as instruções para seu sistema operacional e ambiente de desenvolvimento.

  1. Para definir a VISION_TRAINING KEY variável de ambiente, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua your-training-endpoint pelo ponto de extremidade do seu recurso de treinamento.
  3. Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a VISION_PREDICTION_ENDPOINT variável de ambiente, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a VISION_PREDICTION_RESOURCE_ID variável de ambiente, substitua your-resource-id pelo ID do recurso de previsão.
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

Depois de adicionar as variáveis de ambiente, talvez seja necessário reiniciar todos os programas em execução que lerão as variáveis de ambiente, incluindo a janela do console.

Configuração

Instalar a biblioteca de cliente

Para escrever um aplicativo de análise de imagem com o Custom Vision for Python, você precisará da biblioteca de cliente do Custom Vision. Depois de instalar o Python, execute o seguinte comando no PowerShell ou em uma janela do console:

pip install azure-cognitiveservices-vision-customvision

Criar uma aplicação Python nova

Crie um novo arquivo Python e importe as seguintes bibliotecas.

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

Gorjeta

Quer ver todo o ficheiro de código do início rápido de uma vez? Pode encontrá-lo no GitHub, que contém os exemplos de código deste início rápido.

Crie variáveis para o ponto de extremidade e as chaves do Azure do seu recurso.

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

Modelo de objeto

Nome Descrição
CustomVisionTrainingClient Esta classe lida com a criação, treinamento e publicação de seus modelos.
CustomVisionPredictionClient Essa classe lida com a consulta de seus modelos para previsões de deteção de objetos.
ImagePrediction Essa classe define uma previsão de objeto único em uma única imagem. Ele inclui propriedades para o ID e o nome do objeto, o local da caixa delimitadora do objeto e uma pontuação de confiança.

Exemplos de código

Esses trechos de código mostram como fazer o seguinte com a biblioteca de cliente Custom Vision para Python:

Autenticar o cliente

Instancie um cliente de treinamento e previsão com seu endpoint e chaves. Crie objetos ApiKeyServiceClientCredentials com suas chaves e use-os com seu ponto de extremidade para criar um objeto 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)

Criar um novo projeto de Visão Personalizada

Adicione o código seguinte ao seu script para criar um novo projeto do serviço de Visão Personalizada.

Consulte o método create_project para especificar outras opções ao criar seu projeto (explicado no guia do portal da Web Criar um detetor ).

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)

Adicionar etiquetas ao projeto

Para criar tags de objeto em seu projeto, adicione o seguinte código:

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

Carregar e etiquetar imagens

Primeiro, faça o download das imagens de exemplo para este projeto. Salve o conteúdo da pasta Imagens de exemplo em seu dispositivo local.

Ao etiquetar imagens em projetos de deteção de objeto, tem de especificar a região de cada objeto etiquetado com coordenadas normalizadas. O código seguinte associa cada uma das imagens de exemplo à respetiva região marcada. As regiões especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são dadas pela ordem seguinte: esquerda, superior, largura, altura.

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 você não tiver um utilitário de clicar e arrastar para marcar as coordenadas das regiões, poderá usar a interface do usuário da Web em Customvision.ai. Neste exemplo, as coordenadas já são fornecidas.

Em seguida, use este mapa de associações para carregar cada imagem de exemplo com suas coordenadas de região (você pode carregar até 64 imagens em um único lote). Adicione o seguinte código.

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

Você precisará alterar o caminho para as imagens com base em onde você baixou o repositório de amostras do SDK do Python dos serviços de IA do Azure anteriormente.

Preparar o projeto

Este código cria a primeira iteração do modelo de previsão.

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)

Gorjeta

Treinar com tags selecionadas

Opcionalmente, você pode treinar apenas em um subconjunto de suas tags aplicadas. Você pode querer fazer isso se ainda não aplicou o suficiente de certas tags, mas você tem o suficiente de outras. Na chamada train_project, defina o parâmetro opcional selected_tags para uma lista das cadeias de caracteres de ID das tags que você deseja usar. O modelo treinará para reconhecer apenas as tags nessa lista.

Publicar a iteração atual

Uma iteração não está disponível no ponto de extremidade de previsão até que seja publicada. O código a seguir torna a iteração atual do modelo disponível para consulta.

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

Testar o ponto de extremidade de previsão

Para enviar uma imagem para o ponto final de predição e obter a mesma, adicione o seguinte código no fim do ficheiro:

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

Executar a aplicação

Execute CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

A saída da aplicação deverá aparecer na consola. Em seguida, você pode verificar se a imagem de teste (encontrada em <base_image_location>/images/Test) está marcada adequadamente e se a região de deteção está correta. Também pode regressar ao site da Visão Personalizada e ver o estado atual do projeto criado recentemente.

Clean up resources (Limpar recursos)

Se desejar implementar o seu próprio projeto de deteção de objetos (ou, em vez disso, experimentar um projeto de classificação de imagens), deve eliminar o projeto de deteção de bifurcação/tesouras deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No Site de Visão Personalizada, navegue para Projetos e selecione o caixote do lixo em O Meu Novo Projeto.

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

Próximos passos

Agora você fez todas as etapas do processo de deteção de objetos no código. Este exemplo executa uma única iteração de treinamento, mas muitas vezes você precisará treinar e testar seu modelo várias vezes para torná-lo mais preciso. O guia seguinte aborda a classificação de imagens, mas os seus princípios são semelhantes à deteção de objetos.

Test and retrain a model (Testar e voltar a preparar um modelo)