Inicio rápido: Creación de un proyecto de detección de objetos con la biblioteca cliente de Custom Vision

Introducción a la biblioteca cliente de Custom Vision para .NET. Siga estos pasos para instalar el paquete y probar el código de ejemplo para crear un modelo de detección de objetos. Creará un proyecto, agregará etiquetas, entrenará el proyecto en las imágenes de ejemplo y usará la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Utilice este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.

Nota

Si desea crear y entrenar un modelo de detección de objetos sin escribir código, consulte la guía basada en explorador en su lugar.

Documentación de referencia | Código fuente de la biblioteca (entrenamiento)(predicción) | Paquete (NuGet) (entrenamiento)(predicción) | Ejemplos

Requisitos previos

Creación de variables de entorno

En este ejemplo, escribirá las credenciales en variables de entorno del equipo local que ejecuta la aplicación.

Vaya a Azure Portal. Si los recursos de Custom Vision que ha creado en la sección Requisitos previos se ha implementado correctamente, seleccione el botón Ir al recurso en Pasos siguientes. Puede encontrar sus claves y puntos de conexión en las páginas de clave y punto de conexión de los recursos, en administración de recursos. Necesitará obtener las claves de los recursos de entrenamiento y predicción, junto con los puntos de conexión de la API.

Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso de predicción en Azure Portal, que aparece como Id. de recurso.

Sugerencia

También use https://www.customvision.ai/ para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración en la parte superior derecha. En las páginas Configuración, puede ver todas las claves, identificadores de recurso y puntos de conexión.

Precaución

No incluya la clave directamente en el código ni la exponga nunca públicamente. Consulte el artículo de Seguridad de servicios de Azure AI para ver más opciones de autenticación, como Azure Key Vault.

Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones correspondientes a su sistema operativo y entorno de desarrollo.

  1. Para establecer la variable de entorno VISION_TRAINING KEY, reemplace your-training-key por una de las claves del recurso de entrenamiento.
  2. Para establecer la variable de entorno VISION_TRAINING_ENDPOINT, reemplace your-training-endpoint por el punto de conexión del recurso de entrenamiento.
  3. Para establecer la variable de entorno VISION_PREDICTION_KEY, reemplace your-prediction-key por una de las claves del recurso de predicción.
  4. Para establecer la variable de entorno VISION_PREDICTION_ENDPOINT, reemplace your-prediction-endpoint por el punto de conexión del recurso de predicción.
  5. Para establecer la variable de entorno VISION_PREDICTION_RESOURCE_ID, reemplace your-resource-id por el id. de recurso del recurso de predicción.
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

Después de agregar las variables de entorno, puede que tenga que reiniciar todos los programas en ejecución que leerán la variable de entorno, incluida la ventana de consola.

Instalación

Creación de una aplicación de C#

En Visual Studio, cree una aplicación de .NET Core.

Instalación de la biblioteca cliente

Después de crear un proyecto, instale la biblioteca cliente; para ello, haga clic con el botón derecho en la solución del proyecto en el Explorador de soluciones y seleccione Administrar paquetes NuGet. En el administrador de paquetes que se abre, seleccione Examinar, marque Incluir versión preliminar y busque Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training y Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Seleccione la versión más reciente y, luego, Instalar.

Sugerencia

¿Desea ver todo el archivo de código de inicio rápido de una vez? Puede encontrarlo en GitHub, que contiene los ejemplos de código de este inicio rápido.

En el directorio del proyecto, abra el archivo program.cs y agregue lo siguiente mediante directivas using:

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

En el método Main de la aplicación, cree variables que recuperen las claves y el punto de conexión del recurso de las variables de entorno. También declarará algunos objetos básicos para usarlos más adelante.

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

En el método Main de la aplicación, agregue llamadas para los métodos que se usan en este inicio rápido. Las implementará más adelante.

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 el cliente

En un nuevo método, cree instancias de clientes de entrenamiento y predicción mediante el punto de conexión y las claves.

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

Creación de un proyecto de Custom Vision

El siguiente método crea un proyecto de detección de objetos. El proyecto creado se mostrará en el sitio web de Custom Vision. Consulte el método CreateProject para especificar otras opciones al crear el proyecto (explicadas en la guía del portal web Creación de un 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;
}

Adición de etiquetas al proyecto

Este método define las etiquetas en las que se va a entrenar el 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");
}

Carga y etiquetado de imágenes

En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta de imágenes de ejemplo en el dispositivo local.

Cuando se etiquetan imágenes en los proyectos de detección de objetos, es preciso especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. El código siguiente asocia cada una de las imágenes del ejemplo a su región etiquetada.

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 sus propios proyectos, si no dispone de una utilidad de hacer clic y arrastrar para marcar las coordenadas de las regiones, puede usar la interfaz de usuario web del sitio web de Custom Vision. En este ejemplo ya se proporcionan las coordenadas.

Luego, esta asignación de asociaciones se usa para cargar cada imagen de ejemplo con sus coordenadas de región. Puede cargar hasta 64 imágenes en un único lote. Es posible que tenga que cambiar el valor imagePath para que apunte a las ubicaciones de carpeta correctas.

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

En este punto, ha cargado todas las imágenes de ejemplo y etiquetado cada una (tenedor o tijeras) con un rectángulo de píxeles asociado.

Entrenamiento del proyecto

Este método crea la primera iteración de entrenamiento del proyecto. Se consulta el servicio hasta que finaliza el entrenamiento.

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

Sugerencia

Entrenamiento con etiquetas seleccionadas

Opcionalmente, puede entrenar solo en un subconjunto de las etiquetas aplicadas. Es posible que desee hacer esto si aún no ha aplicado suficientes etiquetas de un tipo determinado, pero tiene bastantes de las otras. En la llamada a TrainProject, use el parámetro trainingParameters. Construya un parámetro TrainingParameters y establezca su propiedad SelectedTags en una lista de identificadores de las etiquetas que desea usar. El modelo se entrenará para reconocer solo las etiquetas de esa lista.

Publicación de la iteración actual

Este método hace que la iteración actual del modelo esté disponible para realizar consultas. Puede usar el nombre del modelo como referencia para enviar solicitudes de predicción. Debe escribir su propio valor para predictionResourceId. Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso en Azure Portal, que aparece como Id. de recurso.

private void PublishIteration(CustomVisionTrainingClient trainingApi, Project project)
{

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

Prueba del punto de conexión de la predicción

Este método carga la imagen de prueba, consulta el punto de conexión del modelo y envía los datos de la predicción a la consola.

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

Ejecución de la aplicación

Ejecute la aplicación haciendo clic en el botón Depurar en la parte superior de la ventana del IDE.

Cuando se ejecuta la aplicación, se debería abrir una ventana de consola y escribir la salida siguiente:

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 ]

Luego puede comprobar que la imagen de prueba (que se encuentra en Images/Test/) se ha etiquetado correctamente y que la región de detección es correcta. En este momento puede presionar cualquier tecla para salir de la aplicación.

Limpieza de recursos

Si desea implementar su propio proyecto de detección de objetos (o probar un proyecto de clasificación de imágenes), puede que desee eliminar el proyecto de identificación de tenedores o cuchillos de este ejemplo. Una suscripción gratuita sirve para dos proyectos de Custom Vision.

En el sitio web de Custom Vision, vaya a Proyectos y seleccione la papelera en My New Project.

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

Pasos siguientes

Ahora ha realizado cada paso del proceso de detección de objetos en el código. En este ejemplo se ejecuta una sola iteración de entrenamiento, pero a menudo necesitará entrenar y probar el modelo varias veces para hacerlo más preciso. En la guía siguiente se trata la clasificación de imágenes, pero sus principios son similares a los de la detección de objetos.

En esta guía se proporciona información y código de ejemplo para ayudarle a empezar a usar la biblioteca cliente de Custom Vision con Go para crear un modelo de detección de objetos. Podrá crear un proyecto, agregar etiquetas, entrenar el proyecto y utilizar la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Utilice este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.

Nota

Si desea crear y entrenar un modelo de detección de objetos sin escribir código, consulte la guía basada en explorador en su lugar.

Use la biblioteca cliente de Custom Vision para Go para:

  • Creación de un proyecto de Custom Vision
  • Adición de etiquetas al proyecto
  • Carga y etiquetado de imágenes
  • Entrenamiento del proyecto
  • Publicación de la iteración actual
  • Prueba del punto de conexión de la predicción

Documentación de referencia (entrenamiento)(predicción)

Prerrequisitos

  • Una suscripción a Azure: cree una cuenta gratuita
  • Go 1.8+
  • Una vez que tenga la suscripción de Azure, cree un recurso de Custom Vision en Azure Portal para crear un recurso de entrenamiento y predicción y obtener las claves y el punto de conexión.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Creación de variables de entorno

En este ejemplo, escribirá las credenciales en variables de entorno del equipo local que ejecuta la aplicación.

Vaya a Azure Portal. Si los recursos de Custom Vision que ha creado en la sección Requisitos previos se ha implementado correctamente, seleccione el botón Ir al recurso en Pasos siguientes. Puede encontrar sus claves y puntos de conexión en las páginas de clave y punto de conexión de los recursos, en administración de recursos. Necesitará obtener las claves de los recursos de entrenamiento y predicción, junto con los puntos de conexión de la API.

Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso de predicción en Azure Portal, que aparece como Id. de recurso.

Sugerencia

También use https://www.customvision.ai/ para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración en la parte superior derecha. En las páginas Configuración, puede ver todas las claves, identificadores de recurso y puntos de conexión.

Precaución

No incluya la clave directamente en el código ni la exponga nunca públicamente. Consulte el artículo de Seguridad de servicios de Azure AI para ver más opciones de autenticación, como Azure Key Vault.

Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones correspondientes a su sistema operativo y entorno de desarrollo.

  1. Para establecer la variable de entorno VISION_TRAINING KEY, reemplace your-training-key por una de las claves del recurso de entrenamiento.
  2. Para establecer la variable de entorno VISION_TRAINING_ENDPOINT, reemplace your-training-endpoint por el punto de conexión del recurso de entrenamiento.
  3. Para establecer la variable de entorno VISION_PREDICTION_KEY, reemplace your-prediction-key por una de las claves del recurso de predicción.
  4. Para establecer la variable de entorno VISION_PREDICTION_ENDPOINT, reemplace your-prediction-endpoint por el punto de conexión del recurso de predicción.
  5. Para establecer la variable de entorno VISION_PREDICTION_RESOURCE_ID, reemplace your-resource-id por el id. de recurso del recurso de predicción.
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

Después de agregar las variables de entorno, puede que tenga que reiniciar todos los programas en ejecución que leerán la variable de entorno, incluida la ventana de consola.

Instalación

Instalación de la biblioteca cliente de Custom Vision

Para escribir una aplicación de análisis de imágenes con Custom Vision para Go, necesitará la biblioteca cliente del servicio Custom Vision. En PowerShell, ejecute el siguiente comando:

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

O bien, si usa dep, dentro de su repositorio ejecute:

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

Obtención de las imágenes de ejemplo

En este ejemplo se utilizan las imágenes del repositorio Muestras de SDK de Python de servicios de Azure AI de GitHub. Clone o descargue este repositorio en el entorno de desarrollo. Recuerde la ubicación de la carpeta para un paso posterior.

Creación del proyecto de Custom Vision

Cree un archivo denominado sample.go en el directorio del proyecto que prefiera y ábralo en el editor de código que prefiera.

Para crear un proyecto de Custom Vision Service, agregue el siguiente código al script.

Consulte el método CreateProject para especificar otras opciones al crear el proyecto (explicadas en la guía del portal web Creación de un 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, "")

Creación de etiquetas en el proyecto

Para crear etiquetas de clasificación para el proyecto, agregue el código siguiente al final de sample.go:

# Make two tags in the new project
forkTag, _ := trainer.CreateTag(ctx, *project.ID, "fork", "A fork", string(training.Regular))
scissorsTag, _ := trainer.CreateTag(ctx, *project.ID, "scissors", "Pair of scissors", string(training.Regular))

Carga y etiquetado de imágenes

Cuando se etiquetan imágenes en los proyectos de detección de objetos, es preciso especificar la región de cada objeto etiquetado mediante coordenadas normalizadas.

Nota

Si no tiene una utilidad de hacer clic y arrastrar para marcar las coordenadas de las regiones, puede usar la interfaz de usuario web en Customvision.ai. En este ejemplo ya se proporcionan las coordenadas.

Para agregar las imágenes, etiquetas y regiones al proyecto, inserte el siguiente código después de crear la etiqueta. Para este tutorial, las regiones se codificaron de forma rígida en el código. Las regiones especifican el rectángulo delimitador en coordenadas normalizadas y las coordenadas se proporcionan en el siguiente orden: izquierda, superior, ancho y alto.

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

Luego, use esta asignación de asociaciones para cargar cada imagen de ejemplo con sus coordenadas de región (puede cargar hasta 64 imágenes en un único lote). Agregue el código siguiente:

Nota

Tendrá que cambiar la ruta de acceso a las imágenes en función de donde haya descargado anteriormente el proyecto Muestras de SDK Go de servicios de Azure AI.

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

Entrenamiento y publicación del proyecto

Este código crea la primera iteración del modelo de predicción y, después, publica dicha iteración en el punto de conexión de la predicción. El nombre que se da a la iteración publicada se puede utilizar para enviar solicitudes de predicción. Una iteración no está disponible en el punto de conexión de predicción hasta que se publica.

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

Uso del punto de conexión de la predicción

Para enviar una imagen al punto de conexión de la predicción y recuperar la predicción, agregue el código siguiente al final del archivo:

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

Ejecución de la aplicación

Ejecute sample.go.

go run sample.go

La salida de la aplicación debe aparecer en la consola. Luego puede comprobar que la imagen de prueba (que se encuentra en samples/vision/images/Test) se ha etiquetado correctamente y que la región de detección es correcta.

Limpieza de recursos

Si desea implementar su propio proyecto de detección de objetos (o probar un proyecto de clasificación de imágenes), puede que desee eliminar el proyecto de identificación de tenedores o cuchillos de este ejemplo. Una suscripción gratuita sirve para dos proyectos de Custom Vision.

En el sitio web de Custom Vision, vaya a Proyectos y seleccione la papelera en My New Project.

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

Pasos siguientes

Ahora ha realizado cada paso del proceso de detección de objetos en el código. En este ejemplo se ejecuta una sola iteración de entrenamiento, pero a menudo necesitará entrenar y probar el modelo varias veces para hacerlo más preciso. En la guía siguiente se trata la clasificación de imágenes, pero sus principios son similares a los de la detección de objetos.

Comience a usar la biblioteca cliente de Custom Vision para Java con el fin de crear un modelo de detección de objetos. Siga estos pasos para instalar el paquete y probar el código de ejemplo para realizar tareas básicas. Utilice este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.

Nota

Si desea crear y entrenar un modelo de detección de objetos sin escribir código, consulte la guía basada en explorador en su lugar.

Use la biblioteca cliente de Custom Vision para Java realizar las siguientes tareas:

  • Creación de un proyecto de Custom Vision
  • Adición de etiquetas al proyecto
  • Carga y etiquetado de imágenes
  • Entrenamiento del proyecto
  • Publicación de la iteración actual
  • Prueba del punto de conexión de la predicción

Documentación de referencia | Código fuente de la biblioteca (entrenamiento)(predicción) | Artefacto (Maven) (entrenamiento)(predicción) | Ejemplos

Requisitos previos

Creación de variables de entorno

En este ejemplo, escribirá las credenciales en variables de entorno del equipo local que ejecuta la aplicación.

Vaya a Azure Portal. Si los recursos de Custom Vision que ha creado en la sección Requisitos previos se ha implementado correctamente, seleccione el botón Ir al recurso en Pasos siguientes. Puede encontrar sus claves y puntos de conexión en las páginas de clave y punto de conexión de los recursos, en administración de recursos. Necesitará obtener las claves de los recursos de entrenamiento y predicción, junto con los puntos de conexión de la API.

Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso de predicción en Azure Portal, que aparece como Id. de recurso.

Sugerencia

También use https://www.customvision.ai/ para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración en la parte superior derecha. En las páginas Configuración, puede ver todas las claves, identificadores de recurso y puntos de conexión.

Precaución

No incluya la clave directamente en el código ni la exponga nunca públicamente. Consulte el artículo de Seguridad de servicios de Azure AI para ver más opciones de autenticación, como Azure Key Vault.

Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones correspondientes a su sistema operativo y entorno de desarrollo.

  1. Para establecer la variable de entorno VISION_TRAINING KEY, reemplace your-training-key por una de las claves del recurso de entrenamiento.
  2. Para establecer la variable de entorno VISION_TRAINING_ENDPOINT, reemplace your-training-endpoint por el punto de conexión del recurso de entrenamiento.
  3. Para establecer la variable de entorno VISION_PREDICTION_KEY, reemplace your-prediction-key por una de las claves del recurso de predicción.
  4. Para establecer la variable de entorno VISION_PREDICTION_ENDPOINT, reemplace your-prediction-endpoint por el punto de conexión del recurso de predicción.
  5. Para establecer la variable de entorno VISION_PREDICTION_RESOURCE_ID, reemplace your-resource-id por el id. de recurso del recurso de predicción.
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

Después de agregar las variables de entorno, puede que tenga que reiniciar todos los programas en ejecución que leerán la variable de entorno, incluida la ventana de consola.

Instalación

Creación de un proyecto de Gradle

En una ventana de la consola (como cmd, PowerShell o Bash), cree un directorio para la aplicación y vaya a él.

mkdir myapp && cd myapp

Ejecute el comando gradle init desde el directorio de trabajo. Este comando creará archivos de compilación esenciales para Gradle, como build.gradle.kts, que se usa en tiempo de ejecución para crear y configurar la aplicación.

gradle init --type basic

Cuando se le solicite que elija un DSL, seleccione Kotlin.

Instalación de la biblioteca cliente

Busque build.gradle.kts y ábralo con el IDE o el editor de texto que prefiera. A continuación, cópielo en la siguiente configuración de compilación. Esta configuración define el proyecto como una aplicación Java cuyo punto de entrada es la clase CustomVisionQuickstart. Importa las bibliotecas de 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")
}

Creación de un archivo Java

En el directorio de trabajo, ejecute el siguiente comando para crear una carpeta de origen del proyecto:

mkdir -p src/main/java

Vaya a la nueva carpeta y cree un archivo denominado CustomVisionQuickstart.java. Ábralo en el editor o el IDE que prefiera y agregue las siguientes instrucciones import:

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

import com.google.common.io.ByteStreams;

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

Sugerencia

¿Desea ver todo el archivo de código de inicio rápido de una vez? Puede encontrarlo en GitHub, que contiene los ejemplos de código de este inicio rápido.

En la clase CustomVisionQuickstart de la aplicación, cree variables que recuperen las claves y el punto de conexión del recurso de las variables de entorno.

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

En el método main de la aplicación, agregue llamadas para los métodos que se usan en este inicio rápido. Se definirán más adelante.

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

Modelo de objetos

Las siguientes clases e interfaces determinan algunas de las características principales de la biblioteca cliente de Custom Vision para Java.

Nombre Descripción
CustomVisionTrainingClient Esta clase controla la creación, el entrenamiento y la publicación de los modelos.
CustomVisionPredictionClient Esta clase controla la consulta de las predicciones de detección de objetos en los modelos.
ImagePrediction Esta clase define una sola predicción de objetos en una sola imagen. Se incluyen las propiedades del identificador y el nombre del objeto, la ubicación del rectángulo delimitador del objeto y una puntuación de confianza.

Ejemplos de código

Estos fragmentos de código muestran cómo realizar las siguientes tareas con la biblioteca cliente de Custom Vision para Java:

Autenticar el cliente

En el método main, cree instancias de clientes de entrenamiento y predicción mediante su punto de conexión y claves.

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

Creación de un proyecto de Custom Vision

El siguiente método crea un proyecto de detección de objetos. El proyecto creado se mostrará en el sitio web de Custom Vision que ha visitado anteriormente. Consulte las sobrecargas del método CreateProject para especificar otras opciones al crear el proyecto (explicadas en la guía del portal web Creación de un 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;
}

Adición de etiquetas al proyecto

Este método define las etiquetas en las que se va a entrenar el 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();
}

Carga y etiquetado de imágenes

En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta de imágenes de ejemplo en el dispositivo local.

Nota

¿Necesita un conjunto de imágenes más amplio para completar el entrenamiento? Trove, un proyecto de Microsoft Garage, le permite recopilar y comprar conjuntos de imágenes con fines de aprendizaje. Una vez que haya recopilado sus imágenes, puede descargarlas y, a continuación, importarlas en el proyecto de Custom Vision de la manera habitual. Visite la página de Trove para más información.

Cuando se etiquetan imágenes en los proyectos de detección de objetos, es preciso especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. El código siguiente asocia cada una de las imágenes del ejemplo a su región etiquetada.

Nota

Si no tiene una utilidad de hacer clic y arrastrar para marcar las coordenadas de las regiones, puede usar la interfaz de usuario web en Customvision.ai. En este ejemplo ya se proporcionan las coordenadas.

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

El siguiente bloque de código agrega las imágenes al proyecto. Deberá cambiar los argumentos de las llamadas de GetImage para que apunten a las ubicaciones de las carpetas fork y scissors que descargó.

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

El fragmento de código anterior usa dos funciones auxiliares que recuperan las imágenes como flujos de recursos y las cargan en el servicio (puede cargar hasta 64 imágenes en un único lote). Defina estos 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;
}

Entrenamiento del proyecto

Este método crea la primera iteración de entrenamiento del proyecto. Se consulta el servicio hasta que finaliza el entrenamiento.

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

Publicación de la iteración actual

Este método hace que la iteración actual del modelo esté disponible para realizar consultas. Puede usar el nombre del modelo como referencia para enviar solicitudes de predicción. Debe escribir su propio valor para predictionResourceId. Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso en Azure Portal, que aparece como Id. de recurso.

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

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

Prueba del punto de conexión de la predicción

Este método carga la imagen de prueba, consulta el punto de conexión del modelo y envía los datos de la predicción a la consola.

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

Ejecución de la aplicación

Puede compilar la aplicación con:

gradle build

Ejecute la aplicación con el comando gradle run:

gradle run

Limpieza de recursos

Si quiere limpiar y eliminar una suscripción de servicios de Azure AI, puede eliminar el recurso o el grupo de recursos. Al eliminar el grupo de recursos, también se elimina cualquier otro recurso que esté asociado a él.

Si desea implementar su propio proyecto de detección de objetos (o probar un proyecto de clasificación de imágenes), puede que desee eliminar el proyecto de identificación de tenedores o cuchillos de este ejemplo. Una suscripción gratuita sirve para dos proyectos de Custom Vision.

En el sitio web de Custom Vision, vaya a Proyectos y seleccione la papelera en My New Project.

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

Pasos siguientes

Ahora ha realizado cada paso del proceso de detección de objetos en el código. En este ejemplo se ejecuta una sola iteración de entrenamiento, pero a menudo necesitará entrenar y probar el modelo varias veces para hacerlo más preciso. En la guía siguiente se trata la clasificación de imágenes, pero sus principios son similares a los de la detección de objetos.

  • ¿Qué es Custom Vision?
  • El código fuente correspondiente a este ejemplo se encuentra disponible en GitHub.

En esta guía se proporcionan instrucciones y código de ejemplo para ayudarle a empezar a usar la biblioteca cliente de Custom Vision para Node.js a fin de crear un modelo de detección de objetos. Podrá crear un proyecto, agregar etiquetas, entrenar el proyecto y utilizar la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Utilice este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.

Nota

Si desea crear y entrenar un modelo de detección de objetos sin escribir código, consulte la guía basada en explorador en su lugar.

Use la biblioteca cliente de Custom Vision para .NET para hacer lo siguiente:

  • Creación de un proyecto de Custom Vision
  • Adición de etiquetas al proyecto
  • Carga y etiquetado de imágenes
  • Entrenamiento del proyecto
  • Publicación de la iteración actual
  • Prueba del punto de conexión de la predicción

Documentación de referencia (entrenamiento)(predicción) | Código fuente de la biblioteca (entrenamiento)(predicción) | Paquete (npm) (entrenamiento)(predicción) | Ejemplos

Requisitos previos

  • Una suscripción a Azure: cree una cuenta gratuita
  • La versión actual de Node.js
  • Una vez que tenga la suscripción de Azure, cree un recurso de Custom Vision en Azure Portal para crear un recurso de entrenamiento y predicción.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Creación de variables de entorno

En este ejemplo, escribirá las credenciales en variables de entorno del equipo local que ejecuta la aplicación.

Vaya a Azure Portal. Si los recursos de Custom Vision que ha creado en la sección Requisitos previos se ha implementado correctamente, seleccione el botón Ir al recurso en Pasos siguientes. Puede encontrar sus claves y puntos de conexión en las páginas de clave y punto de conexión de los recursos, en administración de recursos. Necesitará obtener las claves de los recursos de entrenamiento y predicción, junto con los puntos de conexión de la API.

Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso de predicción en Azure Portal, que aparece como Id. de recurso.

Sugerencia

También use https://www.customvision.ai/ para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración en la parte superior derecha. En las páginas Configuración, puede ver todas las claves, identificadores de recurso y puntos de conexión.

Precaución

No incluya la clave directamente en el código ni la exponga nunca públicamente. Consulte el artículo de Seguridad de servicios de Azure AI para ver más opciones de autenticación, como Azure Key Vault.

Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones correspondientes a su sistema operativo y entorno de desarrollo.

  1. Para establecer la variable de entorno VISION_TRAINING KEY, reemplace your-training-key por una de las claves del recurso de entrenamiento.
  2. Para establecer la variable de entorno VISION_TRAINING_ENDPOINT, reemplace your-training-endpoint por el punto de conexión del recurso de entrenamiento.
  3. Para establecer la variable de entorno VISION_PREDICTION_KEY, reemplace your-prediction-key por una de las claves del recurso de predicción.
  4. Para establecer la variable de entorno VISION_PREDICTION_ENDPOINT, reemplace your-prediction-endpoint por el punto de conexión del recurso de predicción.
  5. Para establecer la variable de entorno VISION_PREDICTION_RESOURCE_ID, reemplace your-resource-id por el id. de recurso del recurso de predicción.
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

Después de agregar las variables de entorno, puede que tenga que reiniciar todos los programas en ejecución que leerán la variable de entorno, incluida la ventana de consola.

Instalación

Creación de una aplicación Node.js

En una ventana de la consola (como cmd, PowerShell o Bash), cree un directorio para la aplicación y vaya a él.

mkdir myapp && cd myapp

Ejecute el comando npm init para crear una aplicación de nodo con un archivo package.json.

npm init

Instalación de la biblioteca cliente

Para escribir una aplicación de análisis de imágenes con Custom Vision para Node.js, necesitará los paquetes NPM de Custom Vision. Para instalarlos ,ejecute el comando siguiente en PowerShell:

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

el archivo package.json de la aplicación se actualizará con las dependencias.

Cree un archivo llamado index.js e importe las bibliotecas siguientes:

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

Sugerencia

¿Desea ver todo el archivo de código de inicio rápido de una vez? Puede encontrarlo en GitHub, que contiene los ejemplos de código de este inicio rápido.

Cree variables para el punto de conexión y las claves de Azure del 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"];

Agregue también campos para el nombre del proyecto y un parámetro de tiempo de espera para las llamadas asincrónicas.

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

Modelo de objetos

Nombre Descripción
TrainingAPIClient Esta clase controla la creación, el entrenamiento y la publicación de los modelos.
PredictionAPIClient Esta clase controla la consulta de las predicciones de detección de objetos en los modelos.
Predicción Esta interfaz define una sola predicción en una sola imagen. Incluye las propiedades para el identificador y el nombre de objeto, y una puntuación de confianza.

Ejemplos de código

Estos fragmentos de código muestran cómo realizar las siguientes tareas con la biblioteca cliente de Custom Vision para JavaScript:

Autenticar el cliente

Cree una instancia de objetos de cliente con la clave y el punto de conexión. Cree un objeto ApiKeyCredentials con la clave, y úselo con el punto de conexión para crear un objeto TrainingAPIClient y un objeto 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);

Incorporación de una función auxiliar

Agregue la siguiente función para ayudar a realizar varias llamadas asincrónicas. La utilizará más adelante.

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

Creación de un proyecto de Custom Vision

Inicie una nueva función para incluir todas las llamadas a funciones de Custom Vision. Para crear un nuevo proyecto del servicio Custom Vision, agregue el siguiente código.

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

Adición de etiquetas al proyecto

Para crear etiquetas de clasificación para el proyecto, agregue el código siguiente a la función:

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

Carga y etiquetado de imágenes

En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta de imágenes de ejemplo en el dispositivo local.

Para agregar las imágenes de ejemplo al proyecto, inserte el siguiente código después de crear la etiqueta. Este código carga cada imagen con su etiqueta correspondiente. Cuando se etiquetan imágenes en los proyectos de detección de objetos, es preciso especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. Para este tutorial, las regiones se codificaron de forma rígida alineadas con el código. Las regiones especifican el rectángulo delimitador en coordenadas normalizadas y las coordenadas se proporcionan en el siguiente orden: izquierda, superior, ancho y alto. Puede cargar hasta 64 imágenes en un ú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

Tendrá que cambiar la ruta de acceso a las imágenes (sampleDataRoot) en función del lugar en el que descargó anteriormente el repositorio de muestras del SDK de Python de servicios de Azure AI.

Nota

Si no tiene una utilidad de hacer clic y arrastrar para marcar las coordenadas de las regiones, puede usar la interfaz de usuario web en Customvision.ai. En este ejemplo ya se proporcionan las coordenadas.

Entrenamiento del proyecto

Este código crea la primera iteración del modelo de predicción.

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

Publicación de la iteración actual

Este código publica la iteración entrenada en el punto de conexión de predicción. El nombre que se da a la iteración publicada se puede utilizar para enviar solicitudes de predicción. Una iteración no está disponible en el punto de conexión de la predicción hasta que se publica.

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

Prueba del punto de conexión de la predicción

Para enviar una imagen al punto de conexión de la predicción y recuperar la predicción, agregue el código siguiente a la función.

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

A continuación, cierre la función de Custom Vision y llámela.

})()

Ejecución de la aplicación

Ejecute la aplicación con el comando node en el archivo de inicio rápido.

node index.js

La salida de la aplicación debe aparecer en la consola. Después, compruebe que la imagen de prueba (que se encuentra en <sampleDataRoot>/Test/) se haya etiquetado correctamente y que la región de detección sea correcta. También puede volver al sitio web de Custom Vision y ver el estado actual del proyecto recién creado.

Limpieza de recursos

Si desea implementar su propio proyecto de detección de objetos (o probar un proyecto de clasificación de imágenes), puede que desee eliminar el proyecto de identificación de tenedores o cuchillos de este ejemplo. Una suscripción gratuita sirve para dos proyectos de Custom Vision.

En el sitio web de Custom Vision, vaya a Proyectos y seleccione la papelera en My New Project.

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

Pasos siguientes

Ahora ha realizado cada paso del proceso de detección de objetos en el código. En este ejemplo se ejecuta una sola iteración de entrenamiento, pero a menudo necesitará entrenar y probar el modelo varias veces para hacerlo más preciso. En la guía siguiente se trata la clasificación de imágenes, pero sus principios son similares a los de la detección de objetos.

Introducción a la biblioteca cliente de Custom Vision para Python. Siga estos pasos para instalar el paquete y probar el código de ejemplo para crear un modelo de detección de objetos. Podrá crear un proyecto, agregar etiquetas, entrenar el proyecto y utilizar la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Utilice este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.

Nota

Si desea crear y entrenar un modelo de detección de objetos sin escribir código, consulte la guía basada en explorador en su lugar.

Use la biblioteca cliente de Custom Vision para Python con los fines siguientes:

  • Creación de un proyecto de Custom Vision
  • Adición de etiquetas al proyecto
  • Carga y etiquetado de imágenes
  • Entrenamiento del proyecto
  • Publicación de la iteración actual
  • Prueba del punto de conexión de la predicción

Documentación de referencia | Código fuente de la biblioteca | Paquete (PyPI) | Ejemplos

Prerrequisitos

  • Una suscripción a Azure: cree una cuenta gratuita
  • Python 3.x
    • La instalación de Python debe incluir pip. Puede comprobar si tiene pip instalado mediante la ejecución de pip --version en la línea de comandos. Para obtener pip, instale la versión más reciente de Python.
  • Una vez que tenga la suscripción de Azure, cree un recurso de Custom Vision en Azure Portal para crear un recurso de entrenamiento y predicción.
    • Puede usar el plan de tarifa gratis (F0) para probar el servicio y actualizarlo más adelante a un plan de pago para producción.

Creación de variables de entorno

En este ejemplo, escribirá las credenciales en variables de entorno del equipo local que ejecuta la aplicación.

Vaya a Azure Portal. Si los recursos de Custom Vision que ha creado en la sección Requisitos previos se ha implementado correctamente, seleccione el botón Ir al recurso en Pasos siguientes. Puede encontrar sus claves y puntos de conexión en las páginas de clave y punto de conexión de los recursos, en administración de recursos. Necesitará obtener las claves de los recursos de entrenamiento y predicción, junto con los puntos de conexión de la API.

Encontrará el identificador del recurso de predicción en la pestaña de Propiedades del recurso de predicción en Azure Portal, que aparece como Id. de recurso.

Sugerencia

También use https://www.customvision.ai/ para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración en la parte superior derecha. En las páginas Configuración, puede ver todas las claves, identificadores de recurso y puntos de conexión.

Precaución

No incluya la clave directamente en el código ni la exponga nunca públicamente. Consulte el artículo de Seguridad de servicios de Azure AI para ver más opciones de autenticación, como Azure Key Vault.

Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones correspondientes a su sistema operativo y entorno de desarrollo.

  1. Para establecer la variable de entorno VISION_TRAINING KEY, reemplace your-training-key por una de las claves del recurso de entrenamiento.
  2. Para establecer la variable de entorno VISION_TRAINING_ENDPOINT, reemplace your-training-endpoint por el punto de conexión del recurso de entrenamiento.
  3. Para establecer la variable de entorno VISION_PREDICTION_KEY, reemplace your-prediction-key por una de las claves del recurso de predicción.
  4. Para establecer la variable de entorno VISION_PREDICTION_ENDPOINT, reemplace your-prediction-endpoint por el punto de conexión del recurso de predicción.
  5. Para establecer la variable de entorno VISION_PREDICTION_RESOURCE_ID, reemplace your-resource-id por el id. de recurso del recurso de predicción.
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

Después de agregar las variables de entorno, puede que tenga que reiniciar todos los programas en ejecución que leerán la variable de entorno, incluida la ventana de consola.

Instalación

Instalación de la biblioteca cliente

Para escribir una aplicación de análisis de imágenes con Custom Vision para Python, necesitará la biblioteca cliente de Custom Vision. Después de instalar Python, ejecute el siguiente comando en PowerShell o en una ventana de consola:

pip install azure-cognitiveservices-vision-customvision

Creación de una nueva aplicación de Python

Cree un archivo de Python e importe las bibliotecas siguientes.

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

Sugerencia

¿Desea ver todo el archivo de código de inicio rápido de una vez? Puede encontrarlo en GitHub, que contiene los ejemplos de código de este inicio rápido.

Cree variables para el punto de conexión y las claves de Azure del recurso.

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

Modelo de objetos

Nombre Descripción
CustomVisionTrainingClient Esta clase controla la creación, el entrenamiento y la publicación de los modelos.
CustomVisionPredictionClient Esta clase controla la consulta de las predicciones de detección de objetos en los modelos.
ImagePrediction Esta clase define una sola predicción de objetos en una sola imagen. Se incluyen las propiedades del identificador y el nombre del objeto, la ubicación del rectángulo delimitador del objeto y una puntuación de confianza.

Ejemplos de código

Estos fragmentos de código muestran cómo realizar las siguientes tareas con la biblioteca cliente de Custom Vision para Python:

Autenticar el cliente

Cree instancias de clientes de entrenamiento y predicción mediante su punto de conexión y claves. Cree objetos ApiKeyServiceClientCredentials con sus claves y úselos con el punto de conexión para crear un objeto CustomVisionTrainingClient y un objeto CustomVisionPredictionClient.

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

Creación de un proyecto de Custom Vision

Para crear un proyecto de Custom Vision Service, agregue el siguiente código al script.

Consulte el método create_project para especificar otras opciones al crear el proyecto (explicadas en la guía del portal web Creación de un detector).

publish_iteration_name = "detectModel"

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

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

Adición de etiquetas al proyecto

Para crear etiquetas de objeto en el proyecto, agregue el código siguiente:

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

Carga y etiquetado de imágenes

En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta de imágenes de ejemplo en el dispositivo local.

Cuando se etiquetan imágenes en los proyectos de detección de objetos, es preciso especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. El código siguiente asocia cada una de las imágenes del ejemplo a su región etiquetada. Las regiones especifican el rectángulo delimitador en coordenadas normalizadas y las coordenadas se proporcionan en el siguiente orden: izquierda, superior, ancho y alto.

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

Si no tiene una utilidad de hacer clic y arrastrar para marcar las coordenadas de las regiones, puede usar la interfaz de usuario web en Customvision.ai. En este ejemplo ya se proporcionan las coordenadas.

Luego, use esta asignación de asociaciones para cargar cada imagen de ejemplo con sus coordenadas de región (puede cargar hasta 64 imágenes en un único lote). Agregue el código siguiente:

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

Tendrá que cambiar la ruta de acceso a las imágenes en función del lugar en el que descargó el repositorio de muestras del SDK de Python de servicios de Azure AI.

Entrenamiento del proyecto

Este código crea la primera iteración del modelo de predicción.

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)

Sugerencia

Entrenamiento con etiquetas seleccionadas

Opcionalmente, puede entrenar solo en un subconjunto de las etiquetas aplicadas. Es posible que desee hacer esto si aún no ha aplicado suficientes etiquetas de un tipo determinado, pero tiene bastantes de las otras. En la llamada a train_project , establezca el parámetro opcional selected_tags en una lista de las cadenas de identificadores de las etiquetas que desea usar. El modelo se entrenará para reconocer solo las etiquetas de esa lista.

Publicación de la iteración actual

Una iteración no está disponible en el punto de conexión de la predicción hasta que se publica. El siguiente código hace que la iteración actual del modelo esté disponible para realizar consultas.

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

Prueba del punto de conexión de la predicción

Para enviar una imagen al punto de conexión de la predicción y recuperar la predicción, agregue el código siguiente al final del archivo:

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

Ejecución de la aplicación

Ejecute CustomVisionQuickstart.py.

python CustomVisionQuickstart.py

La salida de la aplicación debe aparecer en la consola. Después, compruebe que la imagen de prueba (que se encuentra en <base_image_location>/images/Test) se haya etiquetado correctamente y que la región de detección sea correcta. También puede volver al sitio web de Custom Vision y ver el estado actual del proyecto recién creado.

Limpieza de recursos

Si desea implementar su propio proyecto de detección de objetos (o probar un proyecto de clasificación de imágenes), puede que desee eliminar el proyecto de identificación de tenedores o cuchillos de este ejemplo. Una suscripción gratuita sirve para dos proyectos de Custom Vision.

En el sitio web de Custom Vision, vaya a Proyectos y seleccione la papelera en My New Project.

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

Pasos siguientes

Ahora ha realizado cada paso del proceso de detección de objetos en el código. En este ejemplo se ejecuta una sola iteración de entrenamiento, pero a menudo necesitará entrenar y probar el modelo varias veces para hacerlo más preciso. En la guía siguiente se trata la clasificación de imágenes, pero sus principios son similares a los de la detección de objetos.