Início Rápido: Criar um projeto de detecção de objeto com o SDK de Visão Personalizada para JavaQuickstart: Create an object detection project with the Custom Vision SDK for Java

Este artigo fornece informações e exemplos de código para ajudar você a começar a usar o SDK de Visão Personalizada com Java a fim de criar um modelo de detecção de objeto.This article provides information and sample code to help you get started using the Custom Vision SDK with Java to build an object detection model. Depois de criada, você poderá adicionar regiões marcadas, fazer upload de imagens, treinar o projeto, obter a URL de ponto de extremidade de previsão do projeto padrão e usar o ponto de extremidade para testar programaticamente uma imagem.After it's created, you can add tagged regions, upload images, train the project, obtain the project's default prediction endpoint URL, and use the endpoint to programmatically test an image. Use este exemplo como modelo para criar seu próprio aplicativo Java.Use this example as a template for building your own Java application.

Pré-requisitosPrerequisites

  • Um Java IDE de sua preferênciaA Java IDE of your choice
  • JDK 7 ou 8 instalado.JDK 7 or 8 installed.
  • Maven instaladoMaven installed

Obter o SDK de Visão Personalizada e um exemplo de códigoGet the Custom Vision SDK and sample code

Para escrever um aplicativo Java que usa a Visão Personalizada, você precisará dos pacotes de maven da Visão Personalizada.To write a Java app that uses Custom Vision, you'll need the Custom Vision maven packages. Esses pacotes estão incluídos no projeto de exemplo que você baixará, mas é possível acessá-los individualmente aqui.These packages are included in the sample project you will download, but you can access them individually here.

Você pode instalar o SDK de Visão Personalizada do repositório central do Maven:You can install the Custom Vision SDK from maven central repository:

Clone ou baixe o projeto Exemplos de SDK de Java dos Serviços Cognitivos.Clone or download the Cognitive Services Java SDK Samples project. Navegue até a pasta Vision/CustomVision/ .Navigate to the Vision/CustomVision/ folder.

Esse projeto Java cria um novo projeto de detecção de objeto da Visão Personalizada denominado Sample Java OD Project, que pode ser acessado no site da Visão Personalizada.This Java project creates a new Custom Vision object detection project named Sample Java OD Project, which can be accessed through the Custom Vision website. Ele então carrega as imagens para treinar e testar um classificador.It then uploads images to train and test a classifier. Neste projeto, o classificador serve para determinar se uma árvore é uma Cicuta ou uma Cerejeira.In this project, the classifier is intended to determine whether a tree is a Hemlock or a Japanese Cherry.

Obter as chaves de treinamento e previsãoGet the training and prediction keys

O projeto precisa de um conjunto de chaves de assinatura válido para interagir com o serviço.The project needs a valid set of subscription keys in order to interact with the service. Para obter um conjunto de chaves de avaliação gratuita, vá para o site do Serviço de Visão Personalizada e entre com uma conta da Microsoft.To get a set of free trial keys, go to the Custom Vision website and sign in with a Microsoft account. Selecione o ícone de engrenagem no canto superior direito.Select the gear icon in the upper right. Na seção Contas, veja os valores dos campos Chave de Treinamento, Chave de Previsão e ID do Recurso de Previsão.In the Accounts section, see the values in the Training Key, Prediction Key and Prediction Resource Id fields. Você precisará delas mais tarde.You will need these later.

Imagem da interface do usuário de chaves

O programa está configurado para armazenar seus dados de chave como variáveis de ambiente.The program is configured to store your key data as environment variables. Defina essas variáveis navegando até a pasta Vision/CustomVision no PowerShell.Set these variables by navigating to the Vision/CustomVision folder in PowerShell. Em seguida, insira os comandos:Then enter the commands:

$env:AZURE_CUSTOMVISION_TRAINING_API_KEY ="<your training api key>"
$env:AZURE_CUSTOMVISION_PREDICTION_API_KEY ="<your prediction api key>"

Compreender o códigoUnderstand the code

Carregue o projeto Vision/CustomVision em seu Java IDE e abra o arquivo CustomVisionSamples.java.Load the Vision/CustomVision project in your Java IDE and open the CustomVisionSamples.java file. Localize o método runSample e comente a chamada de método ImageClassification_Sample – esse método executa o cenário de classificação de imagens, que não é abordado neste guia.Find the runSample method and comment out the ImageClassification_Sample method call—this method executes the image classification scenario, which is not covered in this guide. O método ObjectDetection_Sample implementa a funcionalidade principal desse início rápido; navegue até sua definição e inspecione o código.The ObjectDetection_Sample method implements the primary functionality of this quickstart; navigate to its definition and inspect the code.

Criar um novo projeto do Serviço de Visão PersonalizadaCreate a new Custom Vision Service project

Vá até o bloco de código que cria um cliente de treinamento e um projeto de detecção de objeto.Go to the code block that creates a training client and an object detection project. O projeto criado será exibido no site da Visão Personalizada visitado anteriormente.The created project will show up on the Custom Vision website that you visited earlier. 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).See the CreateProject method overloads to specify other options when you create your project (explained in the Build a detector web portal guide).

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

System.out.println("Object Detection Sample");
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) {

Adicionar marcas ao seu projetoAdd tags to your project

        objectDetectionDomain = domain;
        break;
    }
}

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

// <snippet_create_od>

Carregar e marcar imagensUpload and tag images

Ao marcar imagens em projetos de detecção de objeto, você precisa especificar a região de cada objeto marcado usando coordenadas normalizadas.When you tag images in object detection projects, you need to specify the region of each tagged object using normalized coordinates. Vá até a definição do Mapa regionMap.Go to the definition of the regionMap Map. Esse código associa cada uma das imagens de exemplo à região marcada.This code associates each of the sample images with its tagged region.

            .withImageData(testImage)
            .execute();

        for (Prediction prediction: results.predictions())
        {
            System.out.println(String.format("\t%s: %.2f%%", prediction.tagName(), prediction.probability() * 100.0f));
        }
        // </snippet_predict>
    } catch (Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

public static void ObjectDetection_Sample(CustomVisionTrainingClient trainClient, CustomVisionPredictionClient predictor)
{
    try {
        // <snippet_od_mapping>
        // 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 });

Em seguida, vá até o bloco de código que adiciona as imagens ao projeto.Then, skip to the code block that adds the images to the project. As imagens são lidas da pasta src/main/resources do projeto e carregadas no serviço com as marcas e coordenadas de região pertinentes.The images are read from the src/main/resources folder of the project and are uploaded to the service with their appropriate tags and region coordinates.

// 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();
// </snippet_create_od>

// <snippet_tags_od>
// create fork tag
Tag forkTag = trainer.createTag()

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).The previous code snippet makes use of two helper functions that retrieve the images as resource streams and upload them to the service (you can upload up to 64 images in a single batch).

        // String url = "some url";
        // ImagePrediction results = predictor.predictions().detectImageUrl()
        //                         .withProjectId(project.id())
        //                         .withPublishedName(publishedModelName)
        //                         .withUrl(url)
        //                         .execute();

        // <snippet_prediction_od>
        // 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()
            ));
        }
        // </snippet_prediction_od>
    } catch (Exception e) {
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

// <snippet_helpers>
private static void AddImageToProject(Trainings trainer, Project project, String fileName, byte[] contents, UUID tag, double[] regionValues)

Treinar o projeto e publicarTrain the project and publish

Este código cria a primeira iteração no projeto e, em seguida, a publica no ponto de extremidade de previsão.This code creates the first iteration in the project and then publishes that iteration to the prediction endpoint. O nome dado à iteração publicada pode ser usado para enviar solicitações de previsão.The name given to the published iteration can be used to send prediction requests. Uma iteração não fica disponível no ponto de extremidade de previsão até ser publicada.An iteration is not available in the prediction endpoint until it is published.

    .withName("fork")
    .execute();

// create scissors tag
Tag scissorsTag = trainer.createTag()
    .withProjectId(project.id())
    .withName("scissor")
    .execute();
// </snippet_tags_od>

Usar o ponto de extremidade de previsãoUse the prediction endpoint

O ponto de extremidade de previsão, representado aqui pelo objeto predictor, é a referência que você usa para enviar uma imagem para o modelo atual e obter uma previsão de classificação.The prediction endpoint, represented by the predictor object here, is the reference that you use to submit an image to the current model and get a classification prediction. Neste exemplo, predictor é definido em outro lugar usando a variável de ambiente de chave de previsão.In this sample, predictor is defined elsewhere using the prediction key environment variable.

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

// <snippet_train_od>
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());

// The iteration is now trained. Publish it to the prediction endpoint.

Executar o aplicativoRun the application

Para compilar e executar a solução usando o maven, execute o seguinte comando no diretório do projeto no PowerShell:To compile and run the solution using maven, run the following command in the project directory in PowerShell:

mvn compile exec:java

Exiba a saída de console para registro em log e resultados de previsão.View the console output for logging and prediction results. Em seguida, você pode verificar se a imagem de teste foi marcada corretamente e se a região da detecção está correta.You can then verify that the test image is tagged appropriately and that the region of detection is correct.

Limpar recursosClean up resources

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.If you wish to implement your own object detection project (or try an image classification project instead), you may want to delete the fork/scissors detection project from this example. Uma avaliação gratuita permite dois projetos de Visão Personalizada.A free trial allows for two Custom Vision projects.

No site de Visão Personalizada, navegue até Projetos e selecione a Lixeira em Meu novo projeto.On the Custom Vision website, navigate to Projects and select the trash can under My New Project.

Captura de tela de um painel rotulado Meu novo projeto com um ícone de lixeira

Próximas etapasNext steps

Agora você viu como cada etapa do processo de detecção de objeto pode ser executada em código.Now you have seen how every step of the object detection process can be done in code. 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.This sample executes a single training iteration, but often you will need to train and test your model multiple times in order to make it more accurate. O guia a seguir lida com a classificação de imagens, mas seus princípios são semelhantes aos da detecção de objetos.The following guide deals with image classification, but its principles are similar to object detection.