Início Rápido: Criar um projeto de detecção de objetos com a biblioteca de clientes da Visão Personalizada

Introdução à biblioteca de clientes da Visão Personalizada para .NET. Siga estas etapas para instalar o pacote e experimentar o código de exemplo para criar um modelo de detecção de objetos. Você criará um projeto, adicionará marcas, 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 o próprio aplicativo de reconhecimento de imagem.

Observação

Se desejar criar e treinar um modelo de detecção de objetos sem escrever código, confira as diretrizes baseadas em navegador.

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

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará as credenciais em variáveis de ambiente no computador local que está executando o aplicativo.

Acesse o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos tiverem sido implantados com sucesso, selecione o botão Acessar o Recurso em Próximas Etapas. Encontre as chaves e os pontos de extremidade nas páginas de chave e ponto de extremidade dos recursos, em gerenciamento de recursos. Você precisará obter as chaves para os recursos de treinamento e de previsão, juntamente com os pontos de extremidades da API.

Encontre a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Dica

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

Cuidado

Não inclua a chave diretamente no código e nunca a divulgue publicamente. Confira 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 do console e siga as instruções do sistema operacional e do ambiente de desenvolvimento.

  1. Para definir a variável de ambiente VISION_TRAINING KEY, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a variável de ambiente VISION_TRAINING_ENDPOINT, substitua your-training-endpoint pelo ponto de extremidade do recurso de treinamento.
  3. Para definir a variável de ambiente VISION_PREDICTION_KEY, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a variável de ambiente VISION_PREDICTION_ENDPOINT, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a variável de ambiente VISION_PREDICTION_RESOURCE_ID, 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, é aconselhável reiniciar todos os programas em execução que precisarem lê-las, incluindo a janela do console.

Configurando

Criar um aplicativo em C#

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

Instalar a biblioteca de clientes

Depois de criar um projeto, instale a biblioteca de clientes 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 pesquise Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training e Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Selecione a versão mais recente e escolha Instalar.

Dica

Deseja exibir todo o arquivo de código do início rápido de uma vez? Você pode encontrá-lo no GitHub, que contém os exemplos de código neste início rápido.

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

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

No método Main do aplicativo, crie variáveis que recuperem as chaves e os pontos de extremidade de variáveis de ambiente. Você também declarará alguns objetos básicos para 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 guia de início rápido. Você os implementará 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, crie uma instância de clientes de treinamento e previsão usando o ponto de extremidade e as 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

O próximo método cria um projeto de detecção de objeto. O projeto criado será exibido no site da Visão Personalizada. Confira o método CreateProject para especificar outras opções ao criar seu projeto (explicado no guia do portal da Web Criar um detector).

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 marcas ao projeto

Esse método define as marcas em que 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 marcar imagens

Primeiro, baixe as imagens de exemplo para este projeto. Salve o conteúdo da pasta de imagens de exemplo em seu dispositivo local.

Ao marcar imagens em projetos de detecção de objeto, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas. O código a seguir associa cada uma das imagens de exemplo à 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 } }
    };

Observação

Em seus projetos, se você não tiver um utilitário do tipo "clicar e arrastar" para marcar as coordenadas das regiões, use a interface do usuário da Web no site da Web da Visão Personalizada. Neste exemplo, as coordenadas já foram fornecidas.

Em seguida, esse mapa de associações é usado para carregar cada imagem de exemplo com suas coordenadas de região. Você pode carregar até 64 imagens em um único lote. Talvez seja necessário alterar o valor imagePath 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 (bifurcação ou tesoura) com um retângulo de pixel associado.

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

Dica

Fazer o treinamento com marcas selecionadas

Opcionalmente, você pode treinar apenas um subconjunto de suas marcas aplicadas. Talvez seja interessante fazer isso se você ainda não tiver aplicado um número suficiente de determinadas marcas, mas tiver outras delas. Na chamada TrainProject, use o parâmetro trainingParameters. Construa um TrainingParameters e defina a propriedade SelectedTags dele como uma lista de IDs das marcas que você deseja usar. O modelo será treinado para reconhecer apenas as marcas nessa lista.

Publicar a iteração atual

Esse método disponibiliza a iteração atual do modelo para consulta. Você pode usar o nome do modelo como uma referência para enviar solicitações de previsão. Você precisa inserir o seu valor para predictionResourceId. Encontre a ID do recurso de previsão na guia Propriedades do recurso no portal do Azure, listado 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

Este 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 o aplicativo

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

Enquanto o aplicativo é executado, ele deve abrir uma janela do console e gravar a seguinte saída:

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 ]

Em seguida, você pode verificar se a imagem de teste (encontrada em Images/Test/) foi marcada corretamente e se a região da detecção está correta. Aqui você pode pressionar qualquer tecla para sair do aplicativo.

Limpar os recursos

Se você deseja implementar seu próprio projeto de detecção de objeto (ou experimentar um projeto de classificação de imagens em vez disso), você talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos da Visão Personalizada.

No site de Visão Personalizada, navegue até Projetos e selecione a Lixeira em Meu novo projeto.

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

Próximas etapas

Agora, você concluiu cada etapa do processo de detecção de objetos no código. Este exemplo executa uma iteração de treinamento única, mas muitas vezes você precisará treinar e testar o modelo várias vezes para torná-lo mais preciso. O guia a seguir lida com a classificação de imagens, mas seus princípios são semelhantes aos da detecção de objetos.

Este guia fornece informações e um código de exemplo para ajudar você a começar a usar a biblioteca de clientes da Visão Personalizada para Go, a fim de criar um modelo de detecção de objetos. Você criará um projeto, adicionará marcas, 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 o próprio aplicativo de reconhecimento de imagem.

Observação

Se desejar criar e treinar um modelo de detecção de objetos sem escrever código, confira as diretrizes baseadas em navegador.

Use a biblioteca de clientes da Visão Personalizada para Go para:

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

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

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará as credenciais em variáveis de ambiente no computador local que está executando o aplicativo.

Acesse o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos tiverem sido implantados com sucesso, selecione o botão Acessar o Recurso em Próximas Etapas. Encontre as chaves e os pontos de extremidade nas páginas de chave e ponto de extremidade dos recursos, em gerenciamento de recursos. Você precisará obter as chaves para os recursos de treinamento e de previsão, juntamente com os pontos de extremidades da API.

Encontre a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Dica

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

Cuidado

Não inclua a chave diretamente no código e nunca a divulgue publicamente. Confira 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 do console e siga as instruções do sistema operacional e do ambiente de desenvolvimento.

  1. Para definir a variável de ambiente VISION_TRAINING KEY, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a variável de ambiente VISION_TRAINING_ENDPOINT, substitua your-training-endpoint pelo ponto de extremidade do recurso de treinamento.
  3. Para definir a variável de ambiente VISION_PREDICTION_KEY, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a variável de ambiente VISION_PREDICTION_ENDPOINT, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a variável de ambiente VISION_PREDICTION_RESOURCE_ID, 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, é aconselhável reiniciar todos os programas em execução que precisarem lê-las, incluindo a janela do console.

Configurando

Instalar a biblioteca de clientes da Visão Personalizada

Para escrever um aplicativo de análise de imagem com a Visão Personalizada para Go, você precisará da biblioteca de clientes do serviço de Visão Personalizada. Execute o seguinte comando no PowerShell:

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

ou, se você usar o dep, execute o seguinte no repositório:

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

Obter as imagens de exemplo

Esse exemplo usa as imagens do repositório de Amostras do SDK do Python dos Serviços de IA do Azure no GitHub. Clone ou baixe este repositório para o seu ambiente de desenvolvimento. Lembre-se da localização da pasta para uso em uma etapa posterior.

Criar o projeto de Visão Personalizada

Crie um 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 a seguir ao seu script para criar um novo projeto do Serviço de Visão Personalizada.

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

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 marcas no projeto

Para criar marcas de classificação para o 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 marcar imagens

Ao marcar imagens em projetos de detecção de objeto, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas.

Observação

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

Para adicionar imagens, marcas e regiões ao projeto, insira o código a seguir após a criação da marca. Observe que, neste tutorial, as regiões são embutidas em código. As regiões de especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são fornecidas na ordem: esquerda, superior, largura e 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 esse 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 código seguinte:

Observação

Você precisará alterar o caminho para as imagens com base no local onde baixou o projeto de Amostras do SDK do Go para os Serviços de IA do Azure 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

Este 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 fica disponível no ponto de extremidade de previsão até ser 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))

Usar 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 ao final do arquivo:

    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 o aplicativo

Execute sample.go.

go run sample.go

A saída do aplicativo deve aparecer no console. Em seguida, você pode verificar se a imagem de teste (encontrada em samples/vision/images/Test) foi marcada corretamente e se a região da detecção está correta.

Limpar os recursos

Se você deseja implementar seu próprio projeto de detecção de objeto (ou experimentar um projeto de classificação de imagens em vez disso), você talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos da Visão Personalizada.

No site de Visão Personalizada, navegue até Projetos e selecione a Lixeira em Meu novo projeto.

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

Próximas etapas

Agora, você concluiu cada etapa do processo de detecção de objetos no código. Este exemplo executa uma iteração de treinamento única, mas muitas vezes você precisará treinar e testar o modelo várias vezes para torná-lo mais preciso. O guia a seguir lida com a classificação de imagens, mas seus princípios são semelhantes aos da detecção de objetos.

Comece a usar a biblioteca de clientes da Visão Personalizada para Java a fim de criar um modelo de detecção de objeto. Siga essas etapas para instalar o pacote e testar o código de exemplo para tarefas básicas. Use este exemplo como um modelo para criar o próprio aplicativo de reconhecimento de imagem.

Observação

Se desejar criar e treinar um modelo de detecção de objetos sem escrever código, confira as diretrizes baseadas em navegador.

Use a biblioteca de clientes da Visão Personalizada para Java a fim de:

  • Criar um novo projeto de Visão Personalizada
  • Adicionar marcas ao projeto
  • Carregar e marcar imagens
  • Treinar 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 (treinamento)(previsão) | Artifact (Maven) (treinamento)(previsão) | Exemplos

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará as credenciais em variáveis de ambiente no computador local que está executando o aplicativo.

Acesse o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos tiverem sido implantados com sucesso, selecione o botão Acessar o Recurso em Próximas Etapas. Encontre as chaves e os pontos de extremidade nas páginas de chave e ponto de extremidade dos recursos, em gerenciamento de recursos. Você precisará obter as chaves para os recursos de treinamento e de previsão, juntamente com os pontos de extremidades da API.

Encontre a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Dica

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

Cuidado

Não inclua a chave diretamente no código e nunca a divulgue publicamente. Confira 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 do console e siga as instruções do sistema operacional e do ambiente de desenvolvimento.

  1. Para definir a variável de ambiente VISION_TRAINING KEY, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a variável de ambiente VISION_TRAINING_ENDPOINT, substitua your-training-endpoint pelo ponto de extremidade do recurso de treinamento.
  3. Para definir a variável de ambiente VISION_PREDICTION_KEY, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a variável de ambiente VISION_PREDICTION_ENDPOINT, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a variável de ambiente VISION_PREDICTION_RESOURCE_ID, 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, é aconselhável reiniciar todos os programas em execução que precisarem lê-las, incluindo a janela do console.

Configurando

Criar um novo projeto Gradle

Em uma janela de console (como cmd, PowerShell ou Bash), crie um novo diretório para seu aplicativo e navegue até ele.

mkdir myapp && cd myapp

Execute o comando gradle init em seu diretório de trabalho. Esse comando criará arquivos de build essenciais para o Gradle, incluindo o build.gradle.kts, que é usado no runtime para criar e configurar seu aplicativo.

gradle init --type basic

Quando solicitado a escolher uma DSL, escolha Kotlin.

Instalar a biblioteca de clientes

Localize o build.gradle.kts e abra-o com seu IDE ou editor de texto preferencial. Depois copie nessa configuração de build a seguir. Esta configuração define o projeto como um aplicativo Java cujo ponto de entrada é a classe CustomVisionQuickstart. Ela importa as bibliotecas da 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

Em seu diretório de trabalho, execute o comando a seguir 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-a no editor ou IDE de sua preferência e adicione as seguintes instruções import:

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

import com.google.common.io.ByteStreams;

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

Dica

Deseja exibir todo o arquivo de código do início rápido de uma vez? Você pode encontrá-lo no GitHub, que contém os exemplos de código neste início rápido.

Na classe CustomVisionQuickstart do aplicativo, crie variáveis que recuperem as chaves e os pontos de extremidade 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 main do aplicativo, adicione chamadas para os métodos usados neste guia de 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 clientes do Java da Visão Personalizada.

Nome Descrição
CustomVisionTrainingClient Essa classe lida com a criação, o treinamento e a publicação de seus modelos.
CustomVisionPredictionClient Essa classe lida com a consulta de seus modelos para obter previsões de detecção de objetos.
ImagePrediction Essa classe define uma previsão de objeto em uma imagem. Ela inclui propriedades para a ID e o nome do objeto, a localização da caixa delimitadora do objeto e uma pontuação de confiança.

Exemplos de código

Estes snippets de código mostram como realizar as seguintes tarefas com a biblioteca de clientes da Visão Personalizada para Java:

Autenticar o cliente

No método main crie uma instância de clientes de treinamento e previsão usando o ponto de extremidade e as 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

O próximo método cria um projeto de detecção de objeto. O projeto criado será exibido no site da Visão Personalizada visitado anteriormente. Confira as sobrecargas do método CreateProject para especificar outras opções ao criar seu projeto (explicado no guia do portal da Web Criar um detector).

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 marcas ao seu projeto

Esse método define as marcas em que 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 marcar imagens

Primeiro, baixe as imagens de exemplo para este projeto. Salve o conteúdo da pasta de imagens de exemplo em seu dispositivo local.

Observação

Você precisa de um conjunto mais amplo de imagens para concluir o treinamento? O Trove, um projeto da Microsoft Garage, permite coletar e comprar conjuntos de imagens para fins de treinamento. Depois de coletar suas imagens, você pode baixá-las e, em seguida, importá-las para seu projeto de Visão Personalizada da maneira usual. Visite a página do Trove para saber mais.

Ao marcar imagens em projetos de detecção de objeto, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas. O código a seguir associa cada uma das imagens de exemplo à região marcada.

Observação

Se você não tiver um utilitário do tipo "clicar e arrastar" para marcar as coordenadas das regiões, use a interface do usuário da Web em Customvision.ai. Neste exemplo, as coordenadas já foram 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. Será preciso alterar os argumentos das chamadas GetImage de modo que apontem para os locais das pastas fork e scissors 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 snippet de código anterior faz uso de duas funções auxiliares que recuperam as imagens como fluxos de recurso e as carrega no 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;
}

Treinar 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 disponibiliza a iteração atual do modelo para consulta. Você pode usar o nome do modelo como uma referência para enviar solicitações de previsão. Você precisa inserir o seu valor para predictionResourceId. Encontre a ID do recurso de previsão na guia Propriedades do recurso no portal do Azure, listado 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

Este 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 o aplicativo

É possível criar o aplicativo com:

gradle build

Execute o aplicativo com o comando gradle run:

gradle run

Limpar os recursos

Se quiser limpar e remover uma assinatura dos Serviços de IA do Azure, você poderá excluir o recurso ou grupo de recursos. Excluir o grupo de recursos também exclui todos os recursos associados a ele.

Se você deseja implementar seu próprio projeto de detecção de objeto (ou experimentar um projeto de classificação de imagens em vez disso), você talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos da Visão Personalizada.

No site de Visão Personalizada, navegue até Projetos e selecione a Lixeira em Meu novo projeto.

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

Próximas etapas

Agora, você concluiu cada etapa do processo de detecção de objetos no código. Este exemplo executa uma iteração de treinamento única, mas muitas vezes você precisará treinar e testar o modelo várias vezes para torná-lo mais preciso. O guia a seguir lida com a classificação de imagens, mas seus princípios são semelhantes aos da detecção de objetos.

  • O que é Visão Personalizada?
  • O código-fonte dessa amostra pode ser encontrado no GitHub

Este guia fornece informações e um código de exemplo para ajudar você a começar a usar a biblioteca de clientes da Visão Personalizada para Node.js para criar um modelo de detecção de objetos. Você criará um projeto, adicionará marcas, 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 o próprio aplicativo de reconhecimento de imagem.

Observação

Se desejar criar e treinar um modelo de detecção de objetos sem escrever código, confira as diretrizes baseadas em navegador.

Use a biblioteca de clientes da Visão Personalizada para .NET para:

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

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

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você gravará as credenciais em variáveis de ambiente no computador local que está executando o aplicativo.

Acesse o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos tiverem sido implantados com sucesso, selecione o botão Acessar o Recurso em Próximas Etapas. Encontre as chaves e os pontos de extremidade nas páginas de chave e ponto de extremidade dos recursos, em gerenciamento de recursos. Você precisará obter as chaves para os recursos de treinamento e de previsão, juntamente com os pontos de extremidades da API.

Encontre a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Dica

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

Cuidado

Não inclua a chave diretamente no código e nunca a divulgue publicamente. Confira 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 do console e siga as instruções do sistema operacional e do ambiente de desenvolvimento.

  1. Para definir a variável de ambiente VISION_TRAINING KEY, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a variável de ambiente VISION_TRAINING_ENDPOINT, substitua your-training-endpoint pelo ponto de extremidade do recurso de treinamento.
  3. Para definir a variável de ambiente VISION_PREDICTION_KEY, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a variável de ambiente VISION_PREDICTION_ENDPOINT, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a variável de ambiente VISION_PREDICTION_RESOURCE_ID, 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, é aconselhável reiniciar todos os programas em execução que precisarem lê-las, incluindo a janela do console.

Configurando

Criar um novo aplicativo do Node.js

Em uma janela de console (como cmd, PowerShell ou Bash), crie um novo diretório para seu aplicativo e navegue até ele.

mkdir myapp && cd myapp

Execute o comando npm init para criar um aplicativo do Node com um arquivo package.json.

npm init

Instalar a biblioteca de clientes

Para escrever um aplicativo de análise de imagem com a Visão Personalizada para Node.js, você precisará dos pacotes NPM de Visão Personalizada. Para instalá-los, execute o seguinte comando no PowerShell:

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

O arquivo package.json do seu aplicativo 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");

Dica

Deseja exibir todo o arquivo de código do início rápido de uma vez? Você pode encontrá-lo no GitHub, que contém os exemplos de código neste início rápido.

Crie variáveis para as chaves e o ponto de extremidade do Azure do 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"];

Além disso, adicione 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
TrainingAPIClient Essa classe lida com a criação, o treinamento e a publicação de seus modelos.
PredictionAPIClient Essa classe lida com a consulta de seus modelos para obter previsões de detecção de objetos.
Previsão Essa interface define uma previsão em uma imagem. Ela inclui propriedades para a ID e o nome do objeto e uma pontuação de confiança.

Exemplos de código

Estes snippets de código mostram como realizar as seguintes tarefas com a biblioteca de clientes da Visão Personalizada para JavaScript:

Autenticar o cliente

Crie uma instância de objetos do cliente com o ponto de extremidade e a chave. Crie um objeto ApiKeyCredentials com a sua chave e use-o com o 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 função a seguir para ajudar a fazer várias chamadas assíncronas. Você usará isso posteriormente.

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 de Visão Personalizada. Adicione o código a seguir para criar um projeto do 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 marcas ao projeto

Para criar marcas de classificação para o 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 marcar imagens

Primeiro, baixe as imagens de exemplo para este projeto. Salve o conteúdo da pasta de imagens de exemplo em seu dispositivo local.

Para adicionar imagens de exemplo ao projeto, insira o código a seguir após a criação da marca. Esse código carrega cada imagem com sua marca correspondente. Ao marcar imagens em projetos de detecção de objeto, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas. Neste tutorial, as regiões são embutidas no código. As regiões de especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são fornecidas na ordem: esquerda, superior, largura e altura. Você pode carregar até 64 imagens em um ú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 no local onde baixou o repositório de Amostras do SDK do Python dos Serviços de IA do Azure.

Observação

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

Treinar 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

Esse código publica a iteração treinada 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 fica disponível no ponto de extremidade de previsão até ser 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 código a seguir à 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 o aplicativo

Execute o aplicativo com o comando node no seu arquivo de início rápido.

node index.js

A saída do aplicativo deve aparecer no console. Em seguida, você pode verificar se a imagem de teste (encontrada em <sampleDataRoot>/Test/) foi marcada corretamente e se a região da detecção está correta. Você pode também voltar para o site da Visão Personalizada e ver o estado atual do projeto recém-criado.

Limpar os recursos

Se você deseja implementar seu próprio projeto de detecção de objeto (ou experimentar um projeto de classificação de imagens em vez disso), você talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos da Visão Personalizada.

No site de Visão Personalizada, navegue até Projetos e selecione a Lixeira em Meu novo projeto.

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

Próximas etapas

Agora, você concluiu cada etapa do processo de detecção de objetos no código. Este exemplo executa uma iteração de treinamento única, mas muitas vezes você precisará treinar e testar o modelo várias vezes para torná-lo mais preciso. O guia a seguir lida com a classificação de imagens, mas seus princípios são semelhantes aos da detecção de objetos.

Introdução à biblioteca de clientes da Visão Personalizada para Python. Siga estas etapas para instalar o pacote e experimentar o código de exemplo para criar um modelo de detecção de objetos. Você criará um projeto, adicionará marcas, 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 o próprio aplicativo de reconhecimento de imagem.

Observação

Se desejar criar e treinar um modelo de detecção de objetos sem escrever código, confira as diretrizes baseadas em navegador.

Use a biblioteca de clientes da Visão Personalizada para Python a fim de:

  • Criar um novo projeto de Visão Personalizada
  • Adicionar marcas ao projeto
  • Carregar e marcar imagens
  • Treinar 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 | Pacote (PyPI) | Amostras

Pré-requisitos

  • Assinatura do Azure – Criar uma gratuitamente
  • Python 3.x
    • A instalação do Python deve incluir o pip. Você pode executar pip --version na linha de comando para verificar se o pip está instalado. Instale a versão mais recente do Python para obter o pip.
  • Após obter a assinatura do Azure, crie um recurso da Visão Personalizada no portal do Azure para criar um recurso de treinamento e previsão.
    • Use o tipo de preço gratuito (F0) para experimentar o serviço e atualizar mais tarde para um nível pago para produção.

Criar variáveis de ambiente

Neste exemplo, você gravará as credenciais em variáveis de ambiente no computador local que está executando o aplicativo.

Acesse o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos tiverem sido implantados com sucesso, selecione o botão Acessar o Recurso em Próximas Etapas. Encontre as chaves e os pontos de extremidade nas páginas de chave e ponto de extremidade dos recursos, em gerenciamento de recursos. Você precisará obter as chaves para os recursos de treinamento e de previsão, juntamente com os pontos de extremidades da API.

Encontre a ID do recurso de previsão na guia Propriedades do recurso de previsão no portal do Azure, listada como ID do Recurso.

Dica

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

Cuidado

Não inclua a chave diretamente no código e nunca a divulgue publicamente. Confira 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 do console e siga as instruções do sistema operacional e do ambiente de desenvolvimento.

  1. Para definir a variável de ambiente VISION_TRAINING KEY, substitua your-training-key por uma das chaves do recurso de treinamento.
  2. Para definir a variável de ambiente VISION_TRAINING_ENDPOINT, substitua your-training-endpoint pelo ponto de extremidade do recurso de treinamento.
  3. Para definir a variável de ambiente VISION_PREDICTION_KEY, substitua your-prediction-key por uma das chaves do recurso de previsão.
  4. Para definir a variável de ambiente VISION_PREDICTION_ENDPOINT, substitua your-prediction-endpoint pelo ponto de extremidade do recurso de previsão.
  5. Para definir a variável de ambiente VISION_PREDICTION_RESOURCE_ID, 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, é aconselhável reiniciar todos os programas em execução que precisarem lê-las, incluindo a janela do console.

Configurando

Instalar a biblioteca de clientes

Para escrever um aplicativo de análise de imagem com a Visão Personalizada para Python, você precisará da biblioteca de clientes da Visão Personalizada. Depois de instalar o Python, execute o seguinte comando no PowerShell ou em uma janela de console:

pip install azure-cognitiveservices-vision-customvision

Criar um novo aplicativo Python

Crie um arquivo do Python e importe as bibliotecas a seguir.

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

Dica

Deseja exibir todo o arquivo de código do início rápido de uma vez? Você pode encontrá-lo no GitHub, que contém os exemplos de código neste início rápido.

Crie variáveis para as chaves e o ponto de extremidade do Azure do 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 Essa classe lida com a criação, o treinamento e a publicação de seus modelos.
CustomVisionPredictionClient Essa classe lida com a consulta de seus modelos para obter previsões de detecção de objetos.
ImagePrediction Essa classe define uma previsão de objeto em uma imagem. Ela inclui propriedades para a ID e o nome do objeto, a localização da caixa delimitadora do objeto e uma pontuação de confiança.

Exemplos de código

Estes snippets de código mostram como realizar as seguintes tarefas com a biblioteca de clientes da Visão Personalizada para Python:

Autenticar o cliente

Crie um cliente de treinamento e previsão usando seu ponto de extremidade e suas 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 a seguir ao seu script para criar um novo projeto do Serviço de Visão Personalizada.

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

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 marcas ao projeto

Para criar marcas de objeto no 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 marcar imagens

Primeiro, baixe as imagens de exemplo para este projeto. Salve o conteúdo da pasta de imagens de exemplo em seu dispositivo local.

Ao marcar imagens em projetos de detecção de objeto, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas. O código a seguir associa cada uma das imagens de exemplo à região marcada. As regiões de especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são fornecidas na ordem: esquerda, superior, largura e 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 ]
}

Observação

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

Em seguida, use esse 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 código seguinte:

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)

Observação

Você precisará alterar o caminho para as imagens com base no local onde baixou o repositório de Amostras do SDK do Python dos Serviços de IA do Azure anteriormente.

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

Dica

Fazer o treinamento com marcas selecionadas

Opcionalmente, você pode treinar apenas um subconjunto de suas marcas aplicadas. Talvez seja interessante fazer isso se você ainda não tiver aplicado um número suficiente de determinadas marcas, mas tiver outras delas. Na chamada train_project , defina o parâmetro opcional selected_tags como uma lista das cadeias de caracteres de ID das marcas que você deseja usar. O modelo será treinado para reconhecer apenas as marcas nessa lista.

Publicar a iteração atual

Uma iteração não fica disponível no ponto de extremidade de previsão até ser publicada. O código a seguir disponibiliza a iteração atual do modelo 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 de extremidade de previsão e recuperar a previsão, adicione o seguinte código ao final do arquivo:

# 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 o aplicativo

Execute CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

A saída do aplicativo deve aparecer no console. Em seguida, você pode verificar se a imagem de teste (encontrada em <base_image_location>/images/Test) foi marcada corretamente e se a região da detecção está correta. Você pode também voltar para o site da Visão Personalizada e ver o estado atual do projeto recém-criado.

Limpar os recursos

Se você deseja implementar seu próprio projeto de detecção de objeto (ou experimentar um projeto de classificação de imagens em vez disso), você talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos da Visão Personalizada.

No site de Visão Personalizada, navegue até Projetos e selecione a Lixeira em Meu novo projeto.

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

Próximas etapas

Agora, você concluiu cada etapa do processo de detecção de objetos no código. Este exemplo executa uma iteração de treinamento única, mas muitas vezes você precisará treinar e testar o modelo várias vezes para torná-lo mais preciso. O guia a seguir lida com a classificação de imagens, mas seus princípios são semelhantes aos da detecção de objetos.