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

Comece com a biblioteca cliente de 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á tags, treinará o projeto com imagens de exemplo e usará a URL de previsão do projeto para testá-lo de forma programática. 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 detecção de objetos sem escrever código, consulte as diretrizes baseadas no 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ê escreverá suas credenciais em variáveis de ambiente no computador local que executa o aplicativo.

Vá para o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para Recurso nas próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas chaves e ponto de extremidade dos recursos, em Gerenciamento de Recursos. Você precisará obter as chaves para os dois recursos: o de treinamento e o de previsão, juntamente com os endpoints da API.

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

Dica

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

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

  • Para definir a VISION_TRAINING KEY variável de ambiente, substitua <your-training-key> por uma das chaves do recurso de treinamento.
  • Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua <your-training-endpoint> pelo ponto de extremidade do recurso de treinamento.
  • Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua <your-prediction-key> por uma das chaves do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_ENDPOINT ambiente, substitua <your-prediction-endpoint> pelo ponto de extremidade do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_RESOURCE_ID ambiente, substitua <your-resource-id> pela ID do recurso de previsão.

Importante

Recomendamos a autenticação Microsoft Entra ID com identidades gerenciadas para os recursos Azure para evitar armazenar credenciais nos seus aplicativos que são executados na nuvem.

Use chaves de API com cuidado. Não inclua a chave de API diretamente em seu código e nunca a publique publicamente. Se estiver usando chaves de API, armazene-as com segurança em Azure Key Vault, gire as chaves regularmente e restrinja o acesso a Azure Key Vault usando controle de acesso baseado em função e restrições de acesso à rede. Para obter mais informações sobre como usar chaves de API com segurança em seus aplicativos, consulte as chaves API com Azure Key Vault.

Para obter mais informações sobre a segurança dos serviços de IA, consulte Autenticar solicitações para Serviços de IA do Azure.

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 leem as variáveis de ambiente, incluindo a janela do console.

Configurando

Criar um novo aplicativo C#

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

Instalar a biblioteca de clientes

Depois de criar um novo projeto, instale a biblioteca de clientes clicando com o botão direito do mouse na solução de projeto no Gerenciador de Soluções e selecionando Manage NuGet Packages. Na janela do gerenciador de pacotes que se abre, selecione Browse, marque Incluir pré-lançamento e pesquise por Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training e Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Selecione a versão mais recente e, em seguida, instale.

Dica

Deseja exibir todo o arquivo de código de início rápido ao mesmo tempo? Você pode encontrá-lo em 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 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 Principal do aplicativo, crie variáveis que recuperem de variáveis de ambiente as chaves e o endpoint do recurso. 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 Principal do aplicativo, adicione chamadas para os métodos usados neste 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 método inovador, instancie clientes de treinamento e previsão através do 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 detecção de objetos. O projeto criado será exibido 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 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 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 marcar imagens

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

Ao marcar imagens em projetos de detecção de objetos, 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 } }
    };

Nota

Para seus próprios projetos, se você não tiver um utilitário de clique 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.

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 imagePath valor para apontar para os locais corretos da pasta.

    // 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 exemplo e marcou cada uma delas (garfo ou tesoura) com um retângulo de pixels 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

Treinar com etiquetas selecionadas

Opcionalmente, você pode treinar em apenas um subconjunto de suas etiquetas aplicadas. Talvez você queira fazer isso se ainda não aplicou o suficiente de certas tags, mas já 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 marcas que você deseja usar. O modelo treinará para reconhecer apenas as tags 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 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 Properties do recurso no portal Azure, listada como Resource ID.

private void PublishIteration(CustomVisionTrainingClient trainingApi, Project project)
{

    // The iteration is now trained. Publish it to the prediction end point.
    var predictionResourceId = Environment.GetEnvironmentVariable("VISION_PREDICTION_RESOURCE_ID");
    trainingApi.PublishIteration(project.Id, iteration.Id, publishedModelName, predictionResourceId);
    Console.WriteLine("Done!\n");
}

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

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

À medida que 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 Imagens/Teste/) está marcada adequadamente e se a região de detecção está correta. Neste ponto, você pode pressionar qualquer tecla para sair do aplicativo.

Limpar recursos

Se você quiser implementar seu próprio projeto de detecção de objetos (ou tentar um projeto de classificação de imagem), talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No site Custom Vision, navegue até Projetos e selecione a lixeira em Meu Novo Projeto.

Captura de tela de um painel rotulado Meu Novo Projeto com um ícone de lixeira.

Próximas etapas

Agora você fez todas as etapas do processo de detecçã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 a seguir lida com a classificação de imagem, mas seus princípios são semelhantes à detecção de objetos.

Este guia fornece instruções e código de exemplo para ajudá-lo a começar a usar a biblioteca de clientes da Visão Personalizada para Go 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 seu próprio aplicativo de reconhecimento de imagem.

Nota

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

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

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você escreverá suas credenciais em variáveis de ambiente no computador local que executa o aplicativo.

Vá para o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para Recurso nas próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas chaves e ponto de extremidade dos recursos, em Gerenciamento de Recursos. Você precisará obter as chaves para os dois recursos: o de treinamento e o de previsão, juntamente com os endpoints da API.

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

Dica

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

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

  • Para definir a VISION_TRAINING KEY variável de ambiente, substitua <your-training-key> por uma das chaves do recurso de treinamento.
  • Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua <your-training-endpoint> pelo ponto de extremidade do recurso de treinamento.
  • Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua <your-prediction-key> por uma das chaves do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_ENDPOINT ambiente, substitua <your-prediction-endpoint> pelo ponto de extremidade do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_RESOURCE_ID ambiente, substitua <your-resource-id> pela ID do recurso de previsão.

Importante

Recomendamos a autenticação Microsoft Entra ID com identidades gerenciadas para os recursos Azure para evitar armazenar credenciais nos seus aplicativos que são executados na nuvem.

Use chaves de API com cuidado. Não inclua a chave de API diretamente em seu código e nunca a publique publicamente. Se estiver usando chaves de API, armazene-as com segurança em Azure Key Vault, gire as chaves regularmente e restrinja o acesso a Azure Key Vault usando controle de acesso baseado em função e restrições de acesso à rede. Para obter mais informações sobre como usar chaves de API com segurança em seus aplicativos, consulte as chaves API com Azure Key Vault.

Para obter mais informações sobre a segurança dos serviços de IA, consulte Autenticar solicitações para Serviços de IA do Azure.

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 leem as variáveis de ambiente, incluindo a janela do console.

Configurando

Instalar a biblioteca de clientes da Visão Personalizada

Para escrever um aplicativo de análise de imagens utilizando o Custom Vision para Go, você precisará da biblioteca de clientes 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 dep, no seu repositório, execute o seguinte:

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

Obter as imagens de exemplo

Este exemplo usa as imagens do repositório Foundry Tools Python SDK Samples no GitHub. Clone ou baixe esse repositório em seu ambiente de desenvolvimento. Lembre-se da localização da pasta para um passo posterior.

Criar o projeto de Visão Personalizada

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

Adicione o código a seguir ao script para criar um novo projeto de 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 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 tags no projeto

Para criar marcas de classificação ao seu projeto, adicione o seguinte código ao final do 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 objetos, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas.

Nota

Se você não tiver um utilitário de clique 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, tags e regiões ao projeto, insira o código a seguir após a criação da tag. Observe que, neste tutorial, as regiões são codificadas diretamente. As regiões especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são fornecidas na ordem: 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 código a seguir.

Nota

Você precisará alterar o caminho para as imagens com base no local em que você baixou o projeto de Exemplos do SDK do Foundry Tools Go 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 fornecido para a iteração publicada pode ser usado para enviar solicitações de previsão. Uma iteração não está disponível no endpoint 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))

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 exemplos/visão/imagens/teste) está marcada adequadamente e se a região de detecção está correta.

Limpar recursos

Se você quiser implementar seu próprio projeto de detecção de objetos (ou tentar um projeto de classificação de imagem), talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No site Custom Vision, navegue até Projetos e selecione a lixeira em Meu Novo Projeto.

Captura de tela de um painel rotulado Meu Novo Projeto com um ícone de lixeira.

Próximas etapas

Agora você fez todas as etapas do processo de detecçã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 a seguir lida com a classificação de imagem, mas seus princípios são semelhantes à detecção de objetos.

Comece a usar a biblioteca de clientes da Visão Personalizada para Java para criar um modelo de detecçã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 detecção de objetos sem escrever código, consulte as diretrizes baseadas no navegador .

documentação Referência | Código-fonte da biblioteca (treinamento)(previsão)| Artefato (Maven) (treinamento)(previsão) | Exemplos

Pré-requisitos

Criar variáveis de ambiente

Neste exemplo, você escreverá suas credenciais em variáveis de ambiente no computador local que executa o aplicativo.

Vá para o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para Recurso nas próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas chaves e ponto de extremidade dos recursos, em Gerenciamento de Recursos. Você precisará obter as chaves para os dois recursos: o de treinamento e o de previsão, juntamente com os endpoints da API.

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

Dica

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

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

  • Para definir a VISION_TRAINING KEY variável de ambiente, substitua <your-training-key> por uma das chaves do recurso de treinamento.
  • Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua <your-training-endpoint> pelo ponto de extremidade do recurso de treinamento.
  • Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua <your-prediction-key> por uma das chaves do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_ENDPOINT ambiente, substitua <your-prediction-endpoint> pelo ponto de extremidade do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_RESOURCE_ID ambiente, substitua <your-resource-id> pela ID do recurso de previsão.

Importante

Recomendamos a autenticação Microsoft Entra ID com identidades gerenciadas para os recursos Azure para evitar armazenar credenciais nos seus aplicativos que são executados na nuvem.

Use chaves de API com cuidado. Não inclua a chave de API diretamente em seu código e nunca a publique publicamente. Se estiver usando chaves de API, armazene-as com segurança em Azure Key Vault, gire as chaves regularmente e restrinja o acesso a Azure Key Vault usando controle de acesso baseado em função e restrições de acesso à rede. Para obter mais informações sobre como usar chaves de API com segurança em seus aplicativos, consulte as chaves API com Azure Key Vault.

Para obter mais informações sobre a segurança dos serviços de IA, consulte Autenticar solicitações para Serviços de IA do Azure.

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 leem as variáveis de ambiente, incluindo a janela do console.

Configurando

Criar um novo projeto do Gradle

Em uma janela do 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 a partir do seu diretório de trabalho. Esse comando criará arquivos de build essenciais para o Gradle, incluindo build.gradle.kts, que é usado em runtime para criar e configurar seu aplicativo.

gradle init --type basic

Quando solicitado a escolher uma DSL, selecione Kotlin.

Instalar a biblioteca de clientes

Localize build.gradle.kts e abra-o com seu IDE ou editor de texto preferido. Em seguida, copie a configuração de build a seguir. Essa configuração define o projeto como um aplicativo Java cujo ponto de entrada é a classe CustomVisionQuickstart. Ele importa as bibliotecas do Custom Vision.

plugins {
    java
    application
}
application { 
    mainClassName = "CustomVisionQuickstart"
}
repositories {
    mavenCentral()
}
dependencies {
    compile(group = "com.azure", name = "azure-cognitiveservices-customvision-training", version = "1.1.0-preview.2")
    compile(group = "com.azure", name = "azure-cognitiveservices-customvision-prediction", version = "1.1.0-preview.2")
}

Criar um arquivo de 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 preferencial ou IDE 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;

Dica

Deseja exibir todo o arquivo de código de início rápido ao mesmo tempo? Você pode encontrá-lo em 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 o ponto de extremidade do recurso 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 cliente 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 manipula a consulta de seus modelos para previsões de detecção de objetos.
ImagePrediction Essa classe define uma única previsão de objeto em uma única imagem. Ele inclui propriedades para o identificador e o nome do objeto, a localização da caixa delimitadora do objeto e uma pontuação de confiança.

Exemplos de código

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

Autenticar o cliente

Em seu método principal , instancie clientes de treinamento e previsão usando seu ponto de extremidade 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 detecção de objetos. O projeto criado aparecerá no site da Visão Personalizada que você visitou 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 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 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 marcar imagens

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

Nota

Você precisa de um conjunto mais amplo de imagens para concluir seu treinamento? O Trove, um projeto do Microsoft Garage, permite coletar e comprar conjuntos de imagens para fins de treinamento. Depois de coletar suas imagens, você pode baixá-las e 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 objetos, 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.

Nota

Se você não tiver um utilitário de clique 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 argumentos das chamadas de GetImage para apontar para os locais das pastas de 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 usa duas funções auxiliares que recuperam as imagens como fluxos de recursos e as carregam 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 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 Properties do recurso no portal Azure, listada como Resource ID.

public static String publishIterationOD(CustomVisionTrainingClient trainClient, Project project) {
    Trainings trainer = trainClient.trainings();

    // The iteration is now trained. Publish it to the prediction endpoint.
    String publishedModelName = "myModel";
    String predictionID = "<your-prediction-resource-ID>";
    trainer.publishIteration(project.id(), iteration.id(), publishedModelName, predictionID);
    return publishedModelName;
}

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

Você pode criar o aplicativo com:

gradle build

Execute o aplicativo com o gradle run comando:

gradle run

Limpar recursos

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

Se você quiser implementar seu próprio projeto de detecção de objetos (ou tentar um projeto de classificação de imagem), talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No site Custom Vision, navegue até Projetos e selecione a lixeira em Meu Novo Projeto.

Captura de tela de um painel rotulado Meu Novo Projeto com um ícone de lixeira.

Próximas etapas

Agora você fez todas as etapas do processo de detecçã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 a seguir lida com a classificação de imagem, mas seus princípios são semelhantes à detecção de objetos.

Este guia fornece instruções e código de exemplo para ajudá-lo a começar a usar a biblioteca de clientes da Visão Personalizada para Node.js criar um modelo de detecção de objetos. Você cria um projeto, adiciona marcas, treina o projeto e usa 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 detecção de objetos sem escrever código, consulte as diretrizes baseadas no navegador .

Documentação de referência (treinamento)(previsão) | Pacote (npm) (treinamento)(previsão) | Exemplos

Pré-requisitos

  • Azure assinatura – Criar uma gratuitamente
  • A versão atual do Node.js
  • Depois de ter sua assinatura Azure, criar um recurso de Visão Personalizada no portal Azure para criar um recurso de treinamento e previsão.
    • Você pode usar o tipo de preço gratuito (F0) para experimentar o serviço e atualizar posteriormente para uma camada paga para produção.

Criar variáveis de ambiente

Neste exemplo, você escreverá suas credenciais em variáveis de ambiente no computador local que executa o aplicativo.

Vá para o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para Recurso nas próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas chaves e ponto de extremidade dos recursos, em Gerenciamento de Recursos. Você precisará obter as chaves para os dois recursos: o de treinamento e o de previsão, juntamente com os endpoints da API.

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

Dica

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

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

  • Para definir a VISION_TRAINING KEY variável de ambiente, substitua <your-training-key> por uma das chaves do recurso de treinamento.
  • Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua <your-training-endpoint> pelo ponto de extremidade do recurso de treinamento.
  • Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua <your-prediction-key> por uma das chaves do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_ENDPOINT ambiente, substitua <your-prediction-endpoint> pelo ponto de extremidade do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_RESOURCE_ID ambiente, substitua <your-resource-id> pela ID do recurso de previsão.

Importante

Recomendamos a autenticação Microsoft Entra ID com identidades gerenciadas para os recursos Azure para evitar armazenar credenciais nos seus aplicativos que são executados na nuvem.

Use chaves de API com cuidado. Não inclua a chave de API diretamente em seu código e nunca a publique publicamente. Se estiver usando chaves de API, armazene-as com segurança em Azure Key Vault, gire as chaves regularmente e restrinja o acesso a Azure Key Vault usando controle de acesso baseado em função e restrições de acesso à rede. Para obter mais informações sobre como usar chaves de API com segurança em seus aplicativos, consulte as chaves API com Azure Key Vault.

Para obter mais informações sobre a segurança dos serviços de IA, consulte Autenticar solicitações para Serviços de IA do Azure.

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 leem as variáveis de ambiente, incluindo a janela do console.

Configurando

Criar um novo aplicativo Node.js

Em uma janela do 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 Node com um arquivo package.json.

npm init

Instalar a biblioteca de clientes

Para escrever um aplicativo de análise de imagens com Visão Personalizada para Node.js, você precisa dos pacotes npm da 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 aplicativo é atualizado com as dependências.

Crie um arquivo nomeado 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 de início rápido ao mesmo tempo? Você pode encontrá-lo em GitHub, que contém os exemplos de código neste início rápido.

Criar variáveis para o endpoint de Azure e as chaves de acesso 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"];

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

Exemplos de código

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

Autenticar o cliente

Instancie objetos de cliente com seu endpoint e chave. Crie um objeto ApiKeyCredentials com sua chave e utilize-o com o endpoint para criar objetos 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 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 englobar todas as suas chamadas de função do Custom Vision. Adicione o código a seguir 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 marcas ao projeto

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

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

Para adicionar as imagens de exemplo ao projeto, insira o código a seguir logo após a criação da tag. Esse código carrega cada imagem com sua marca correspondente. Ao marcar imagens em projetos de detecção de objetos, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas. Para este tutorial, as regiões são codificadas diretamente no código. As regiões especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são fornecidas na ordem: esquerda, superior, largura, 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ê precisa alterar o caminho para as imagens (sampleDataRoot) com base no local em que você baixou o repositório de Exemplos do SDK Python Ferramentas Foundry.

Nota

Se você não tiver um utilitário de clique 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.

Treinar o projeto

Esse 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 no endpoint de previsão. O nome fornecido para a iteração publicada pode ser usado para enviar solicitações de previsão. Uma iteração não está disponível no endpoint 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 código a seguir à 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 de Visão Personalizada e depois chame-a.

})()

Executar o aplicativo

Execute o aplicativo com o node comando no 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/) está marcada adequadamente e se a região de detecção está correta. Você também pode voltar ao site da Visão Personalizada e ver o estado atual do seu projeto recém-criado.

Limpar recursos

Se você quiser implementar seu próprio projeto de detecção de objetos (ou tentar um projeto de classificação de imagem), talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No site Custom Vision, navegue até Projetos e selecione a lixeira em Meu Novo Projeto.

Captura de tela de um painel rotulado Meu Novo Projeto com um ícone de lixeira.

Próximas etapas

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

Introdução à biblioteca cliente do Custom Vision 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ê cria um projeto, adiciona marcas, treina o projeto e usa 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 detecção de objetos sem escrever código, consulte as diretrizes baseadas no navegador .

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

Pré-requisitos

  • Azure assinatura – Criar uma gratuitamente
  • Python 3.x
    • Sua instalação Python deve incluir pip. Você pode verificar se o pip foi instalado executando pip --version na linha de comando. Para obter o pip, instale a versão mais recente do Python.
  • Depois de ter sua assinatura Azure, criar um recurso de Visão Personalizada no portal Azure para criar um recurso de treinamento e previsão.
    • Você pode usar o tipo de preço gratuito (F0) para experimentar o serviço e atualizar posteriormente para uma camada paga para produção.

Criar variáveis de ambiente

Neste exemplo, você escreverá suas credenciais em variáveis de ambiente no computador local que executa o aplicativo.

Vá para o portal do Azure. Se os recursos da Visão Personalizada que você criou na seção Pré-requisitos forem implantados com êxito, selecione o botão Ir para Recurso nas próximas etapas. Você pode encontrar suas chaves e pontos de extremidade nas páginas chaves e ponto de extremidade dos recursos, em Gerenciamento de Recursos. Você precisará obter as chaves para os dois recursos: o de treinamento e o de previsão, juntamente com os endpoints da API.

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

Dica

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

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

  • Para definir a VISION_TRAINING KEY variável de ambiente, substitua <your-training-key> por uma das chaves do recurso de treinamento.
  • Para definir a VISION_TRAINING_ENDPOINT variável de ambiente, substitua <your-training-endpoint> pelo ponto de extremidade do recurso de treinamento.
  • Para definir a VISION_PREDICTION_KEY variável de ambiente, substitua <your-prediction-key> por uma das chaves do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_ENDPOINT ambiente, substitua <your-prediction-endpoint> pelo ponto de extremidade do recurso de previsão.
  • Para definir a variável de VISION_PREDICTION_RESOURCE_ID ambiente, substitua <your-resource-id> pela ID do recurso de previsão.

Importante

Recomendamos a autenticação Microsoft Entra ID com identidades gerenciadas para os recursos Azure para evitar armazenar credenciais nos seus aplicativos que são executados na nuvem.

Use chaves de API com cuidado. Não inclua a chave de API diretamente em seu código e nunca a publique publicamente. Se estiver usando chaves de API, armazene-as com segurança em Azure Key Vault, gire as chaves regularmente e restrinja o acesso a Azure Key Vault usando controle de acesso baseado em função e restrições de acesso à rede. Para obter mais informações sobre como usar chaves de API com segurança em seus aplicativos, consulte as chaves API com Azure Key Vault.

Para obter mais informações sobre a segurança dos serviços de IA, consulte Autenticar solicitações para Serviços de IA do Azure.

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 leem as variáveis de ambiente, incluindo a janela do console.

Configurando

Instalar a biblioteca de clientes

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

pip install azure-cognitiveservices-vision-customvision

Criar um novo aplicativo Python

Crie um novo arquivo 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 de início rápido ao mesmo tempo? Você pode encontrá-lo em GitHub, que contém os exemplos de código neste início rápido.

Criar variáveis para o endpoint de Azure e as chaves de acesso do recurso.

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

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 manipula a consulta de seus modelos para previsões de detecção de objetos.
ImagePrediction Essa classe define uma única previsão de objeto em uma única imagem. Ele inclui propriedades para o identificador e o nome do objeto, a localização da caixa delimitadora do objeto e uma pontuação de confiança.

Exemplos de código

Esses snippets de código mostram como fazer o seguinte com a biblioteca de clientes da Visão Personalizada para Python:

Autenticar o cliente

Instancie um cliente de treinamento e previsão usando seu endpoint e suas chaves. Crie objetos ApiKeyServiceClientCredentials com suas chaves e use-os com seu endpoint para criar um CustomVisionTrainingClient e um CustomVisionPredictionClient.

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

Criar um novo projeto de Visão Personalizada

Adicione o código a seguir ao script para criar um novo projeto de serviço de Visão Personalizada.

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

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 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 marcar imagens

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

Ao marcar imagens em projetos de detecção de objetos, 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 especificam a caixa delimitadora em coordenadas normalizadas e as coordenadas são fornecidas na ordem: 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 clique 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 código a seguir.

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 no local em que baixou o repositório de amostras do SDK do Foundry Tools Python anteriormente.

Treinar o projeto

Esse 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

Treinar com etiquetas selecionadas

Opcionalmente, você pode treinar em apenas um subconjunto de suas etiquetas aplicadas. Talvez você queira fazer isso se ainda não aplicou o suficiente de certas tags, mas já tem o suficiente de outras. Na chamada train_project, defina o parâmetro opcional selected_tags para uma lista dos IDs das tags que você deseja usar. O modelo é treinado apenas para reconhecer as tags na lista mencionada.

Publicar a iteração atual

Uma iteração não está disponível no endpoint de previsão até que seja 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) está marcada adequadamente e se a região de detecção está correta. Você também pode voltar ao site da Visão Personalizada e ver o estado atual do seu projeto recém-criado.

Limpar recursos

Se você quiser implementar seu próprio projeto de detecção de objetos (ou tentar um projeto de classificação de imagem), talvez queira excluir o projeto de detecção de garfo/tesoura deste exemplo. Uma assinatura gratuita permite dois projetos de Visão Personalizada.

No site Custom Vision, navegue até Projetos e selecione a lixeira em Meu Novo Projeto.

Captura de tela de um painel rotulado Meu Novo Projeto com um ícone de lixeira.

Próximas etapas

Agora você fez todas as etapas do processo de detecçã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 a seguir lida com a classificação de imagem, mas seus princípios são semelhantes à detecção de objetos.