Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
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 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. Use este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.
Nota
Si desea compilar 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
- suscripción a Azure: Crear una gratuita
- La IDE de Visual Studio o la versión actual de .NET Core.
- Una vez que tenga la suscripción de Azure, crear un recurso de Custom Vision en el portal de Azure 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 nivel de pago para producción.
- Puede usar el plan de tarifa gratis (
Creación de variables de entorno
En este ejemplo, escribirá las credenciales en variables de entorno en el equipo local que ejecuta la aplicación.
Vaya al portal de Azure. Si los recursos de Custom Vision que creó en la sección Requisitos previos se implementaron correctamente, seleccione el botón Ir al recurso debajo de Pasos siguientes. Puede encontrar las claves y los puntos de conexión en las páginas Claves y puntos de conexión de los recursos, en Administración de recursos. Deberá obtener las claves para el recurso de entrenamiento y el recurso de predicción, junto con los puntos de conexión de API.
Puede encontrar el identificador de recurso de predicción en la pestaña Propiedades del portal de Azure, listado como Id. de recurso.
Propina
También se usa https://www.customvision.ai para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración situado en la parte superior derecha. En las páginas Configuración , puede ver todas las claves, el identificador de recurso y los puntos de conexión.
Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones del sistema operativo y el entorno de desarrollo.
- Para establecer la variable de entorno
VISION_TRAINING KEY, reemplaza<your-training-key>con una de las claves para tu recurso de entrenamiento. - Para establecer la variable de
VISION_TRAINING_ENDPOINTentorno, reemplace<your-training-endpoint>por el punto de conexión del recurso de entrenamiento. - Para establecer la
VISION_PREDICTION_KEYvariable de entorno, reemplace por<your-prediction-key>una de las claves del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_ENDPOINT, reemplace<your-prediction-endpoint>con el punto de conexión del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_RESOURCE_ID, reemplace<your-resource-id>por el identificador de recurso para su recurso de predicción.
Importante
Se recomienda la autenticación de Microsoft Entra ID con identidades administradas para los recursos de Azure para evitar almacenar credenciales en sus aplicaciones que se ejecutan en la nube.
Use las claves de API con precaución. No incluya la clave de API directamente en el código y nunca la publique públicamente. Si usa claves de API, almacénelas de forma segura en Azure Key Vault, gire las claves periódicamente y restrinja el acceso a Azure Key Vault mediante el control de acceso basado en rol y las restricciones de acceso de red. Para obtener más información sobre el uso de claves de API de forma segura en las aplicaciones, consulte CLAVESAPI con Azure Key Vault.
Para obtener más información sobre la seguridad de los servicios de inteligencia artificial, consulte
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, es posible que tenga que reiniciar los programas en ejecución que lean las variables de entorno, incluida la ventana de la consola.
Configuración
Creación de una nueva aplicación de C#
Con Visual Studio, cree una nueva aplicación .NET Core.
Instalación de la biblioteca cliente
Una vez que haya creado un nuevo proyecto, instale la biblioteca cliente haciendo clic con el botón derecho en la solución del proyecto en la Explorador de soluciones y seleccionando Administrar paquetes NuGet. En el administrador de paquetes que abre select Browse, compruebe Include prerelease y busque Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training y Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction. Seleccione la versión más reciente y, a continuación, Instalar.
Propina
¿Desea ver todo el archivo de código de inicio rápido a la 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 las siguientes using directivas:
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 del recurso y el endpoint de las variables de entorno. También declarará algunos objetos básicos que se usarán 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 a los métodos usados en este inicio rápido. Tú los implementarás 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);
Autenticación del cliente
En un nuevo método, instancie clientes de entrenamiento y predicción utilizando su punto de conexión y 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
Este 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 (se explica en la guía Compilar un portal web de 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 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");
}
Cargar e etiquetar imágenes
En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta sample Images en el dispositivo local.
Al etiquetar imágenes en proyectos de detección de objetos, debe especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. El código siguiente asocia cada una de las imágenes de 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 tiene una utilidad de clic y arrastre para marcar las coordenadas de las regiones, puede usar la interfaz de usuario web en el sitio web de Custom Vision. En este ejemplo, ya se proporcionan las coordenadas.
A continuación, este mapa de asociaciones se usa para cargar cada imagen de ejemplo con sus coordenadas de región. Puede cargar hasta 64 imágenes en un solo lote. Es posible que tenga que cambiar el valor de imagePath para apuntar a las ubicaciones de directorio 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 momento, ha cargado todas las imágenes de muestra y ha etiquetado cada una (fork o scissors) con un rectángulo de píxeles asociado.
Entrenamiento del proyecto
Este método crea la primera iteración de entrenamiento en el proyecto. Consulta el servicio hasta que se complete 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);
}
}
Propina
Entrenar con etiquetas seleccionadas
Opcionalmente, puede entrenar solo en un subconjunto de las etiquetas aplicadas. Es posible que quiera hacerlo si aún no ha aplicado suficientes etiquetas, pero sí tiene suficientes otros. En la llamada TrainProject , use el parámetro trainingParameters . Cree un TrainingParameters y establezca su propiedad SelectedTags en una lista de identificadores de las etiquetas que desea usar. El modelo 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. Puede encontrar el identificador de recurso de predicción en la pestaña Properties del portal de Azure, que se muestra como Id. de origen.
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 predicción
Este método carga la imagen de prueba, consulta el punto de conexión del modelo y genera datos de predicción en 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 de la parte superior de la ventana del IDE.
A medida que se ejecuta la aplicación, debe 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 ]
A continuación, puede comprobar que la imagen de prueba (que se encuentra en Images/Test/) está etiquetada correctamente y que la región de detección es correcta. En este punto, 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 en su lugar), es posible que desee eliminar el proyecto de detección de bifurcaciones o tijeras de este ejemplo. Una suscripción gratuita permite dos proyectos de Custom Vision.
En el sitio web de Custom Vision, ve a Proyectos y haz clic en el icono de la papelera bajo Mi nuevo Proyecto.
Pasos siguientes
Ahora ha realizado todos los pasos del proceso de detección de objetos en el código. Este ejemplo ejecuta una única iteración de entrenamiento, pero a menudo deberá entrenar y probar el modelo varias veces para que sea más precisa. En la siguiente guía se trata la clasificación de imágenes, pero sus principios son similares a la detección de objetos.
- ¿Qué es Custom Vision?
- El código fuente de este ejemplo se puede encontrar en GitHub
- Documentación de referencia del SDK
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 Go para crear un modelo de detección de objetos. Creará un proyecto, agregará etiquetas, entrenará el proyecto y usará la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Use este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.
Nota
Si desea compilar 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 (entrenamiento)(predicción)
Requisitos previos
- suscripción a Azure: Crear una gratuita
- Go 1.8+
- Una vez que tenga la suscripción de Azure, crear un recurso de Custom Vision en el portal de Azure 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 nivel de pago para producción.
- Puede usar el plan de tarifa gratis (
Creación de variables de entorno
En este ejemplo, escribirá las credenciales en variables de entorno en el equipo local que ejecuta la aplicación.
Vaya al portal de Azure. Si los recursos de Custom Vision que creó en la sección Requisitos previos se implementaron correctamente, seleccione el botón Ir al recurso debajo de Pasos siguientes. Puede encontrar las claves y los puntos de conexión en las páginas Claves y puntos de conexión de los recursos, en Administración de recursos. Deberá obtener las claves para el recurso de entrenamiento y el recurso de predicción, junto con los puntos de conexión de API.
Puede encontrar el identificador de recurso de predicción en la pestaña Propiedades del portal de Azure, listado como Id. de recurso.
Propina
También se usa https://www.customvision.ai para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración situado en la parte superior derecha. En las páginas Configuración , puede ver todas las claves, el identificador de recurso y los puntos de conexión.
Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones del sistema operativo y el entorno de desarrollo.
- Para establecer la variable de entorno
VISION_TRAINING KEY, reemplaza<your-training-key>con una de las claves para tu recurso de entrenamiento. - Para establecer la variable de
VISION_TRAINING_ENDPOINTentorno, reemplace<your-training-endpoint>por el punto de conexión del recurso de entrenamiento. - Para establecer la
VISION_PREDICTION_KEYvariable de entorno, reemplace por<your-prediction-key>una de las claves del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_ENDPOINT, reemplace<your-prediction-endpoint>con el punto de conexión del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_RESOURCE_ID, reemplace<your-resource-id>por el identificador de recurso para su recurso de predicción.
Importante
Se recomienda la autenticación de Microsoft Entra ID con identidades administradas para los recursos de Azure para evitar almacenar credenciales en sus aplicaciones que se ejecutan en la nube.
Use las claves de API con precaución. No incluya la clave de API directamente en el código y nunca la publique públicamente. Si usa claves de API, almacénelas de forma segura en Azure Key Vault, gire las claves periódicamente y restrinja el acceso a Azure Key Vault mediante el control de acceso basado en rol y las restricciones de acceso de red. Para obtener más información sobre el uso de claves de API de forma segura en las aplicaciones, consulte CLAVESAPI con Azure Key Vault.
Para obtener más información sobre la seguridad de los servicios de inteligencia artificial, consulte
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, es posible que tenga que reiniciar los programas en ejecución que lean las variables de entorno, incluida la ventana de la consola.
Configuración
Instalación de la biblioteca cliente de Custom Vision
Para escribir una aplicación de análisis de imágenes con Custom Vision for Go, necesitará la biblioteca cliente de Custom Vision Service. Ejecute el siguiente comando en PowerShell:
go get -u github.com/Azure/azure-sdk-for-go/...
o si usas dep, ejecuta en tu repositorio:
dep ensure -add github.com/Azure/azure-sdk-for-go
Obtención de las imágenes de ejemplo
En este ejemplo se usan las imágenes del repositorio Foundry Tools Python SDK Samples en GitHub. Clone o descargue este repositorio en su entorno de desarrollo. Recuerde su ubicación de carpeta para un paso posterior.
Creación del proyecto de Custom Vision
Cree un archivo llamado sample.go en el directorio del proyecto preferido y ábralo en el editor de código preferido.
Agregue el código siguiente al script para crear un nuevo proyecto de servicio custom Vision.
Consulte el método CreateProject para especificar otras opciones al crear el proyecto (se explica en la guía Compilar un portal web de 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 en 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))
Cargar e etiquetar imágenes
Al etiquetar imágenes en proyectos de detección de objetos, debe especificar la región de cada objeto etiquetado mediante coordenadas normalizadas.
Nota
Si no tiene una utilidad de clic y arrastre 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 código siguiente después de la creación de la etiqueta. Tenga en cuenta que en este tutorial las regiones están codificadas de forma rígida. Las regiones especifican el rectángulo de selección en coordenadas normalizadas, y las coordenadas se proporcionan en el siguiente orden: izquierda, arriba, ancho, altura.
forkImageRegions := map[string][4]float64{
"fork_1.jpg": [4]float64{ 0.145833328, 0.3509314, 0.5894608, 0.238562092 },
"fork_2.jpg": [4]float64{ 0.294117659, 0.216944471, 0.534313738, 0.5980392 },
"fork_3.jpg": [4]float64{ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 },
"fork_4.jpg": [4]float64{ 0.254901975, 0.185898721, 0.5232843, 0.594771266 },
"fork_5.jpg": [4]float64{ 0.2365196, 0.128709182, 0.5845588, 0.71405226 },
"fork_6.jpg": [4]float64{ 0.115196079, 0.133611143, 0.676470637, 0.6993464 },
"fork_7.jpg": [4]float64{ 0.164215669, 0.31008172, 0.767156839, 0.410130739 },
"fork_8.jpg": [4]float64{ 0.118872553, 0.318251669, 0.817401946, 0.225490168 },
"fork_9.jpg": [4]float64{ 0.18259804, 0.2136765, 0.6335784, 0.643790841 },
"fork_10.jpg": [4]float64{ 0.05269608, 0.282303959, 0.8088235, 0.452614367 },
"fork_11.jpg": [4]float64{ 0.05759804, 0.0894935, 0.9007353, 0.3251634 },
"fork_12.jpg": [4]float64{ 0.3345588, 0.07315363, 0.375, 0.9150327 },
"fork_13.jpg": [4]float64{ 0.269607842, 0.194068655, 0.4093137, 0.6732026 },
"fork_14.jpg": [4]float64{ 0.143382356, 0.218578458, 0.7977941, 0.295751631 },
"fork_15.jpg": [4]float64{ 0.19240196, 0.0633497, 0.5710784, 0.8398692 },
"fork_16.jpg": [4]float64{ 0.140931368, 0.480016381, 0.6838235, 0.240196079 },
"fork_17.jpg": [4]float64{ 0.305147052, 0.2512582, 0.4791667, 0.5408496 },
"fork_18.jpg": [4]float64{ 0.234068632, 0.445702642, 0.6127451, 0.344771236 },
"fork_19.jpg": [4]float64{ 0.219362751, 0.141781077, 0.5919118, 0.6683006 },
"fork_20.jpg": [4]float64{ 0.180147052, 0.239820287, 0.6887255, 0.235294119 },
}
scissorsImageRegions := map[string][4]float64{
"scissors_1.jpg": [4]float64{ 0.4007353, 0.194068655, 0.259803921, 0.6617647 },
"scissors_2.jpg": [4]float64{ 0.426470578, 0.185898721, 0.172794119, 0.5539216 },
"scissors_3.jpg": [4]float64{ 0.289215684, 0.259428144, 0.403186262, 0.421568632 },
"scissors_4.jpg": [4]float64{ 0.343137264, 0.105833367, 0.332107842, 0.8055556 },
"scissors_5.jpg": [4]float64{ 0.3125, 0.09766343, 0.435049027, 0.71405226 },
"scissors_6.jpg": [4]float64{ 0.379901975, 0.24308826, 0.32107842, 0.5718954 },
"scissors_7.jpg": [4]float64{ 0.341911763, 0.20714055, 0.3137255, 0.6356209 },
"scissors_8.jpg": [4]float64{ 0.231617644, 0.08459154, 0.504901946, 0.8480392 },
"scissors_9.jpg": [4]float64{ 0.170343131, 0.332957536, 0.767156839, 0.403594762 },
"scissors_10.jpg": [4]float64{ 0.204656869, 0.120539248, 0.5245098, 0.743464053 },
"scissors_11.jpg": [4]float64{ 0.05514706, 0.159754932, 0.799019635, 0.730392158 },
"scissors_12.jpg": [4]float64{ 0.265931368, 0.169558853, 0.5061275, 0.606209159 },
"scissors_13.jpg": [4]float64{ 0.241421565, 0.184264734, 0.448529422, 0.6830065 },
"scissors_14.jpg": [4]float64{ 0.05759804, 0.05027781, 0.75, 0.882352948 },
"scissors_15.jpg": [4]float64{ 0.191176474, 0.169558853, 0.6936275, 0.6748366 },
"scissors_16.jpg": [4]float64{ 0.1004902, 0.279036, 0.6911765, 0.477124184 },
"scissors_17.jpg": [4]float64{ 0.2720588, 0.131977156, 0.4987745, 0.6911765 },
"scissors_18.jpg": [4]float64{ 0.180147052, 0.112369314, 0.6262255, 0.6666667 },
"scissors_19.jpg": [4]float64{ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 },
"scissors_20.jpg": [4]float64{ 0.158088237, 0.04047389, 0.6691176, 0.843137264 },
}
A continuación, use este mapa de asociaciones para cargar cada imagen de ejemplo con sus coordenadas de región (puede cargar hasta 64 imágenes en un solo lote). Agregue el código siguiente.
Nota
Tendrá que cambiar la ruta de acceso a las imágenes en función de dónde descargó anteriormente el proyecto de ejemplos del SDK de Foundry Tools Go.
// 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: ®iontest[0],
Top: ®iontest[1],
Width: ®iontest[2],
Height: ®iontest[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:®ion[0],
Top:®ion[1],
Width:®ion[2],
Height:®ion[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 luego publica esa iteración en el endpoint de predicción. El nombre proporcionado a la iteración publicada se puede usar para enviar solicitudes de predicción. Una iteración no estará disponible en el endpoint de predicción hasta que se publique.
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))
Utilice el punto de conexión de predicción
Para enviar una imagen al punto de conexión de 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. A continuación, puede comprobar que la imagen de prueba (que se encuentra en samples/vision/images/Test) está etiquetada 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 en su lugar), es posible que desee eliminar el proyecto de detección de bifurcaciones o tijeras de este ejemplo. Una suscripción gratuita permite dos proyectos de Custom Vision.
En el sitio web de Custom Vision, ve a Proyectos y haz clic en el icono de la papelera bajo Mi nuevo Proyecto.
Pasos siguientes
Ahora ha realizado todos los pasos del proceso de detección de objetos en el código. Este ejemplo ejecuta una única iteración de entrenamiento, pero a menudo deberá entrenar y probar el modelo varias veces para que sea más precisa. En la siguiente guía se trata la clasificación de imágenes, pero sus principios son similares a la detección de objetos.
- ¿Qué es Custom Vision?
- Documentación de referencia del SDK (entrenamiento)
- documentación de referencia del SDK (predicción)
Empiece a usar la biblioteca cliente de Custom Vision para Java para crear un modelo de detección de objetos. Siga estos pasos para instalar el paquete y probar el código de ejemplo para tareas básicas. Use este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.
Nota
Si desea compilar 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)| Artefacto (Maven) (entrenamiento)(predicción) |
Requisitos previos
- Una suscripción Azure: Crear una gratuita
- La versión actual del kit de desarrollo de Java (JDK)
- La herramienta de compilación de Gradle u otro administrador de dependencias.
- Una vez que tenga la suscripción de Azure, crear un recurso de Custom Vision en el portal de Azure 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 nivel de pago para producción.
- Puede usar el plan de tarifa gratis (
Creación de variables de entorno
En este ejemplo, escribirá las credenciales en variables de entorno en el equipo local que ejecuta la aplicación.
Vaya al portal de Azure. Si los recursos de Custom Vision que creó en la sección Requisitos previos se implementaron correctamente, seleccione el botón Ir al recurso debajo de Pasos siguientes. Puede encontrar las claves y los puntos de conexión en las páginas Claves y puntos de conexión de los recursos, en Administración de recursos. Deberá obtener las claves para el recurso de entrenamiento y el recurso de predicción, junto con los puntos de conexión de API.
Puede encontrar el identificador de recurso de predicción en la pestaña Propiedades del portal de Azure, listado como Id. de recurso.
Propina
También se usa https://www.customvision.ai para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración situado en la parte superior derecha. En las páginas Configuración , puede ver todas las claves, el identificador de recurso y los puntos de conexión.
Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones del sistema operativo y el entorno de desarrollo.
- Para establecer la variable de entorno
VISION_TRAINING KEY, reemplaza<your-training-key>con una de las claves para tu recurso de entrenamiento. - Para establecer la variable de
VISION_TRAINING_ENDPOINTentorno, reemplace<your-training-endpoint>por el punto de conexión del recurso de entrenamiento. - Para establecer la
VISION_PREDICTION_KEYvariable de entorno, reemplace por<your-prediction-key>una de las claves del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_ENDPOINT, reemplace<your-prediction-endpoint>con el punto de conexión del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_RESOURCE_ID, reemplace<your-resource-id>por el identificador de recurso para su recurso de predicción.
Importante
Se recomienda la autenticación de Microsoft Entra ID con identidades administradas para los recursos de Azure para evitar almacenar credenciales en sus aplicaciones que se ejecutan en la nube.
Use las claves de API con precaución. No incluya la clave de API directamente en el código y nunca la publique públicamente. Si usa claves de API, almacénelas de forma segura en Azure Key Vault, gire las claves periódicamente y restrinja el acceso a Azure Key Vault mediante el control de acceso basado en rol y las restricciones de acceso de red. Para obtener más información sobre el uso de claves de API de forma segura en las aplicaciones, consulte CLAVESAPI con Azure Key Vault.
Para obtener más información sobre la seguridad de los servicios de inteligencia artificial, consulte
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, es posible que tenga que reiniciar los programas en ejecución que lean las variables de entorno, incluida la ventana de la consola.
Configuración
Creación de un nuevo proyecto de Gradle
En una ventana de consola (como cmd, PowerShell o Bash), cree un directorio para la aplicación y vaya a ella.
mkdir myapp && cd myapp
Ejecute el comando desde el gradle init directorio de trabajo. Este comando creará archivos de compilación esenciales para Gradle, incluido 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 pida que elija un DSL, seleccione Kotlin.
Instalación de la biblioteca cliente
Busque build.gradle.kts y ábralo con su IDE o editor de texto preferidos. A continuación, copie la siguiente configuración de compilación. Esta configuración define el proyecto como una aplicación de 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 de 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. Ábrelo en el editor o IDE de tu preferencia y añade 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;
Propina
¿Desea ver todo el archivo de código de inicio rápido a la 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 principal de la aplicación, agregue llamadas a los métodos usados en este inicio rápido. Los definirá 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 controlan algunas de las características principales de la biblioteca cliente de Custom Vision Java.
| Nombre | Descripción |
|---|---|
| CustomVisionTrainingClient | Esta clase maneja la creación, el entrenamiento y la publicación de sus modelos. |
| CustomVisionPredictionClient | Esta clase gestiona la consulta de tus modelos para las predicciones de detección de objetos. |
| ImagePrediction | Esta clase define una única predicción de objeto en una sola imagen. Incluye propiedades como el identificador y el nombre del objeto, la ubicación del cuadro 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:
- Autenticación del cliente
- Creación de un proyecto de Custom Vision
- Adición de etiquetas al proyecto
- Cargar e etiquetar imágenes
- Entrena el proyecto
- Publicación de la iteración actual
- Probar el endpoint de predicción
Autenticación del cliente
En el método principal, cree instancias de los clientes de entrenamiento y predicción mediante el punto de conexión y las 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
Este siguiente método crea un proyecto de detección de objetos. El proyecto creado se mostrará en el sitio web de Custom Vision que visitó anteriormente. Consulte las sobrecargas del método CreateProject para especificar otras opciones al crear el proyecto (se explica en la guía Construir un Detector en el Portal Web).
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 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();
}
Cargar e etiquetar imágenes
En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta sample Images en el dispositivo local.
Nota
¿Necesita un conjunto más amplio de imágenes para completar el entrenamiento? Trove, un proyecto de Microsoft Garage, le permite recopilar y comprar conjuntos de imágenes con fines de entrenamiento. Una vez que haya recopilado las imágenes, puede descargarlas y, a continuación, importarlas en el proyecto de Custom Vision de la manera habitual. Visite la página Trove para obtener más información.
Al etiquetar imágenes en proyectos de detección de objetos, debe especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. El código siguiente asocia cada una de las imágenes de ejemplo a su región etiquetada.
Nota
Si no tiene una utilidad de clic y arrastre 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á modificar los argumentos de las GetImage llamadas para que apunten a las ubicaciones de las carpetas fork y tijeras 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 solo 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 en el proyecto. Consulta el servicio hasta que se complete 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. Puede encontrar el identificador de recurso de predicción en la pestaña Properties del portal de Azure, que se muestra como Id. de origen.
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 predicción
Este método carga la imagen de prueba, consulta el punto de conexión del modelo y genera datos de predicción en 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 gradle run comando :
gradle run
Limpieza de recursos
Si desea limpiar y quitar 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 eliminan los demás recursos asociados.
Si desea implementar su propio proyecto de detección de objetos (o probar un proyecto de clasificación de imágenes en su lugar), es posible que desee eliminar el proyecto de detección de bifurcaciones o tijeras de este ejemplo. Una suscripción gratuita permite dos proyectos de Custom Vision.
En el sitio web de Custom Vision, ve a Proyectos y haz clic en el icono de la papelera bajo Mi nuevo Proyecto.
Pasos siguientes
Ahora ha realizado todos los pasos del proceso de detección de objetos en el código. Este ejemplo ejecuta una única iteración de entrenamiento, pero a menudo deberá entrenar y probar el modelo varias veces para que sea más precisa. En la siguiente guía se trata la clasificación de imágenes, pero sus principios son similares a la detección de objetos.
- ¿Qué es Custom Vision?
- El código fuente de este ejemplo se puede encontrar 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 para crear un modelo de detección de objetos. Cree un proyecto, agregue etiquetas, entrene el proyecto y use la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Use este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.
Nota
Si desea compilar 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 (entrenamiento)(predicción) | Paquete (npm) (entrenamiento)(predicción) | Samples
Requisitos previos
- suscripción a Azure: Crear una gratuita
- La versión actual de Node.js
- Una vez que tenga la suscripción de Azure, crear un recurso de Custom Vision en el portal de Azure 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 nivel de pago para producción.
- Puede usar el plan de tarifa gratis (
Creación de variables de entorno
En este ejemplo, escribirá las credenciales en variables de entorno en el equipo local que ejecuta la aplicación.
Vaya al portal de Azure. Si los recursos de Custom Vision que creó en la sección Requisitos previos se implementaron correctamente, seleccione el botón Ir al recurso debajo de Pasos siguientes. Puede encontrar las claves y los puntos de conexión en las páginas Claves y puntos de conexión de los recursos, en Administración de recursos. Deberá obtener las claves para el recurso de entrenamiento y el recurso de predicción, junto con los puntos de conexión de API.
Puede encontrar el identificador de recurso de predicción en la pestaña Propiedades del portal de Azure, listado como Id. de recurso.
Propina
También se usa https://www.customvision.ai para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración situado en la parte superior derecha. En las páginas Configuración , puede ver todas las claves, el identificador de recurso y los puntos de conexión.
Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones del sistema operativo y el entorno de desarrollo.
- Para establecer la variable de entorno
VISION_TRAINING KEY, reemplaza<your-training-key>con una de las claves para tu recurso de entrenamiento. - Para establecer la variable de
VISION_TRAINING_ENDPOINTentorno, reemplace<your-training-endpoint>por el punto de conexión del recurso de entrenamiento. - Para establecer la
VISION_PREDICTION_KEYvariable de entorno, reemplace por<your-prediction-key>una de las claves del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_ENDPOINT, reemplace<your-prediction-endpoint>con el punto de conexión del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_RESOURCE_ID, reemplace<your-resource-id>por el identificador de recurso para su recurso de predicción.
Importante
Se recomienda la autenticación de Microsoft Entra ID con identidades administradas para los recursos de Azure para evitar almacenar credenciales en sus aplicaciones que se ejecutan en la nube.
Use las claves de API con precaución. No incluya la clave de API directamente en el código y nunca la publique públicamente. Si usa claves de API, almacénelas de forma segura en Azure Key Vault, gire las claves periódicamente y restrinja el acceso a Azure Key Vault mediante el control de acceso basado en rol y las restricciones de acceso de red. Para obtener más información sobre el uso de claves de API de forma segura en las aplicaciones, consulte CLAVESAPI con Azure Key Vault.
Para obtener más información sobre la seguridad de los servicios de inteligencia artificial, consulte
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, es posible que tenga que reiniciar los programas en ejecución que lean las variables de entorno, incluida la ventana de la consola.
Configuración
Creación de una nueva aplicación de Node.js
En una ventana de consola (como cmd, PowerShell o Bash), cree un directorio para la aplicación y vaya a ella.
mkdir myapp && cd myapp
Ejecute el npm init comando para crear una aplicación de nodo con un package.json archivo.
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, necesita los paquetes npm de Custom Vision. Para instalarlos, ejecute el siguiente comando en PowerShell:
npm install @azure/cognitiveservices-customvision-training
npm install @azure/cognitiveservices-customvision-prediction
El archivo package.json de la aplicación se actualiza con las dependencias.
Cree un archivo denominado 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");
Propina
¿Desea ver todo el archivo de código de inicio rápido a la 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 llamadas asincrónicas.
const publishIterationName = "detectModel";
const setTimeoutPromise = util.promisify(setTimeout);
Modelo de objetos
| Nombre | Descripción |
|---|---|
| TrainingAPIClient | Esta clase maneja la creación, el entrenamiento y la publicación de sus modelos. |
| PredictionAPIClient | Esta clase gestiona la consulta de tus modelos para las predicciones de detección de objetos. |
| Predicción | Esta interfaz define una sola predicción en una sola imagen. Incluye propiedades para el identificador y el nombre 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 JavaScript:
- Autenticación del cliente
- Creación de un proyecto de Custom Vision
- Adición de etiquetas al proyecto
- Cargar e etiquetar imágenes
- Entrena el proyecto
- Publicación de la iteración actual
- Probar el endpoint de predicción
Autenticación del cliente
Cree una instancia de objetos cliente con tu punto de conexión y tu clave. Cree un objeto ApiKeyCredentials con la clave y úselo con el punto de conexión para crear un objeto TrainingAPIClient y 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);
Agregar función auxiliar
Agregue la siguiente función para ayudar a realizar varias llamadas asincrónicas. Lo usarás 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 contener todas las llamadas de función de Custom Vision. Agregue el código siguiente para crear un nuevo proyecto de servicio Custom Vision.
(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 en 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");
Cargar e etiquetar imágenes
En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta sample Images en el dispositivo local.
Para agregar las imágenes de ejemplo al proyecto, inserte el código siguiente después de la creación de la etiqueta. Este código carga cada imagen con su etiqueta correspondiente. Al etiquetar imágenes en proyectos de detección de objetos, debe especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. En este tutorial, las regiones se codifican de forma rígida en línea con el código. Las regiones especifican el rectángulo de selección en coordenadas normalizadas, y las coordenadas se proporcionan en el siguiente orden: izquierda, arriba, ancho, altura. Puede cargar hasta 64 imágenes en un solo 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
Debe cambiar la ruta de acceso a las imágenes (sampleDataRoot) en función de la ubicación en la que descargó el repositorio De ejemplos del SDK de Foundry Tools Python.
Nota
Si no tiene una utilidad de clic y arrastre 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 proporcionado a la iteración publicada se puede usar para enviar solicitudes de predicción. Una iteración no está disponible en el punto de acceso de predicción hasta que se publique.
// Publish the iteration to the end point
await trainer.publishIteration(sampleProject.id, trainingIteration.id, publishIterationName, predictionResourceId);
Prueba del punto de conexión de predicción
Para enviar una imagen al endpoint de predicción y recuperar la predicción, agregue el siguiente código a su 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 Custom Vision y luego llámela.
})()
Ejecución de la aplicación
Ejecute la aplicación con el comando node en su archivo de inicio rápido.
node index.js
La salida de la aplicación debe aparecer en la consola. A continuación, puede comprobar que la imagen de prueba (que se encuentra en <sampleDataRoot>/Test/) está etiquetada correctamente y que la región de detección es 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 en su lugar), es posible que desee eliminar el proyecto de detección de bifurcaciones o tijeras de este ejemplo. Una suscripción gratuita permite dos proyectos de Custom Vision.
En el sitio web de Custom Vision, ve a Proyectos y haz clic en el icono de la papelera bajo Mi nuevo Proyecto.
Pasos siguientes
Ahora ha realizado todos los pasos del proceso de detección de objetos en el código. Este ejemplo ejecuta una única iteración de entrenamiento, pero a menudo necesita entrenar y probar el modelo varias veces para que sea más precisa. En la siguiente guía se trata la clasificación de imágenes, pero sus principios son similares a la detección de objetos.
- ¿Qué es Custom Vision?
- El código fuente de este ejemplo se puede encontrar en GitHub
- Documentación de referencia del SDK (entrenamiento)
- documentación de referencia del SDK (predicción)
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. Cree un proyecto, agregue etiquetas, entrene el proyecto y use la dirección URL del punto de conexión de predicción del proyecto para probarlo mediante programación. Use este ejemplo como plantilla para crear su propia aplicación de reconocimiento de imágenes.
Nota
Si desea compilar 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 | Paquete (PyPI) | Ejemplos
Requisitos previos
- suscripción a Azure: Crear una gratuita
-
Python 3.x
- La instalación de Python debe incluir pip. Puede comprobar si ha instalado pip mediante la ejecución
pip --versionen la línea de comandos. Obtenga pip instalando la versión más reciente de Python.
- La instalación de Python debe incluir pip. Puede comprobar si ha instalado pip mediante la ejecución
- Una vez que tenga la suscripción de Azure, crear un recurso de Custom Vision en el portal de Azure 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 nivel de pago para producción.
- Puede usar el plan de tarifa gratis (
Creación de variables de entorno
En este ejemplo, escribirá las credenciales en variables de entorno en el equipo local que ejecuta la aplicación.
Vaya al portal de Azure. Si los recursos de Custom Vision que creó en la sección Requisitos previos se implementaron correctamente, seleccione el botón Ir al recurso debajo de Pasos siguientes. Puede encontrar las claves y los puntos de conexión en las páginas Claves y puntos de conexión de los recursos, en Administración de recursos. Deberá obtener las claves para el recurso de entrenamiento y el recurso de predicción, junto con los puntos de conexión de API.
Puede encontrar el identificador de recurso de predicción en la pestaña Propiedades del portal de Azure, listado como Id. de recurso.
Propina
También se usa https://www.customvision.ai para obtener estos valores. Después de iniciar sesión, seleccione el icono Configuración situado en la parte superior derecha. En las páginas Configuración , puede ver todas las claves, el identificador de recurso y los puntos de conexión.
Para establecer las variables de entorno, abra una ventana de consola y siga las instrucciones del sistema operativo y el entorno de desarrollo.
- Para establecer la variable de entorno
VISION_TRAINING KEY, reemplaza<your-training-key>con una de las claves para tu recurso de entrenamiento. - Para establecer la variable de
VISION_TRAINING_ENDPOINTentorno, reemplace<your-training-endpoint>por el punto de conexión del recurso de entrenamiento. - Para establecer la
VISION_PREDICTION_KEYvariable de entorno, reemplace por<your-prediction-key>una de las claves del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_ENDPOINT, reemplace<your-prediction-endpoint>con el punto de conexión del recurso de predicción. - Para establecer la variable de entorno
VISION_PREDICTION_RESOURCE_ID, reemplace<your-resource-id>por el identificador de recurso para su recurso de predicción.
Importante
Se recomienda la autenticación de Microsoft Entra ID con identidades administradas para los recursos de Azure para evitar almacenar credenciales en sus aplicaciones que se ejecutan en la nube.
Use las claves de API con precaución. No incluya la clave de API directamente en el código y nunca la publique públicamente. Si usa claves de API, almacénelas de forma segura en Azure Key Vault, gire las claves periódicamente y restrinja el acceso a Azure Key Vault mediante el control de acceso basado en rol y las restricciones de acceso de red. Para obtener más información sobre el uso de claves de API de forma segura en las aplicaciones, consulte CLAVESAPI con Azure Key Vault.
Para obtener más información sobre la seguridad de los servicios de inteligencia artificial, consulte
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, es posible que tenga que reiniciar los programas en ejecución que lean las variables de entorno, incluida la ventana de la consola.
Configuración
Instalación de la biblioteca cliente
Para escribir una aplicación de análisis de imágenes con Custom Vision para Python, necesita 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 nuevo archivo 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
Propina
¿Desea ver todo el archivo de código de inicio rápido a la 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 vprediction_endpointalid values
ENDPOINT = os.environ["VISION_TRAINING_ENDPOINT"]
prediction_endpoint = os.environ["VISION_PREDICTION_ENDPOINT"]
training_key = os.environ["VISION_TRAINING_KEY"]
prediction_key = os.environ["VISION_PREDICTION_KEY"]
prediction_resource_id = os.environ["VISION_PREDICTION_RESOURCE_ID"]
Modelo de objetos
| Nombre | Descripción |
|---|---|
| CustomVisionTrainingClient | Esta clase maneja la creación, el entrenamiento y la publicación de sus modelos. |
| CustomVisionPredictionClient | Esta clase gestiona la consulta de tus modelos para las predicciones de detección de objetos. |
| ImagePrediction | Esta clase define una única predicción de objeto en una sola imagen. Incluye propiedades como el identificador y el nombre del objeto, la ubicación del cuadro delimitador del objeto y una puntuación de confianza. |
Ejemplos de código
Estos fragmentos de código muestran cómo hacer lo siguiente con la biblioteca cliente de Custom Vision para Python:
- Autenticación del cliente
- Creación de un proyecto de Custom Vision
- Adición de etiquetas al proyecto
- Cargar e etiquetar imágenes
- Entrena el proyecto
- Publicación de la iteración actual
- Probar el endpoint de predicción
Autenticación del cliente
Cree una instancia de un cliente de entrenamiento y predicción con el punto de conexión y las claves. Cree objetos ApiKeyServiceClientCredentials con las claves y úselos con el punto de conexión para crear un objeto CustomVisionTrainingClient y CustomVisionPredictionClient.
credentials = ApiKeyCredentials(in_headers={"Training-key": training_key})
trainer = CustomVisionTrainingClient(ENDPOINT, credentials)
prediction_credentials = ApiKeyCredentials(in_headers={"Prediction-key": prediction_key})
predictor = CustomVisionPredictionClient(prediction_endpoint, prediction_credentials)
Creación de un proyecto de Custom Vision
Agregue el código siguiente al script para crear un nuevo proyecto de servicio custom Vision.
Consulte el método create_project para especificar otras opciones al crear el proyecto (se explica en la guía compilar un portal web de 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")
Cargar e etiquetar imágenes
En primer lugar, descargue las imágenes de ejemplo de este proyecto. Guarde el contenido de la carpeta sample Images en el dispositivo local.
Al etiquetar imágenes en proyectos de detección de objetos, debe especificar la región de cada objeto etiquetado mediante coordenadas normalizadas. El código siguiente asocia cada una de las imágenes de ejemplo a su región etiquetada. Las regiones especifican el rectángulo de selección en coordenadas normalizadas, y las coordenadas se proporcionan en el siguiente orden: izquierda, arriba, ancho, altura.
fork_image_regions = {
"fork_1": [ 0.145833328, 0.3509314, 0.5894608, 0.238562092 ],
"fork_2": [ 0.294117659, 0.216944471, 0.534313738, 0.5980392 ],
"fork_3": [ 0.09191177, 0.0682516545, 0.757352948, 0.6143791 ],
"fork_4": [ 0.254901975, 0.185898721, 0.5232843, 0.594771266 ],
"fork_5": [ 0.2365196, 0.128709182, 0.5845588, 0.71405226 ],
"fork_6": [ 0.115196079, 0.133611143, 0.676470637, 0.6993464 ],
"fork_7": [ 0.164215669, 0.31008172, 0.767156839, 0.410130739 ],
"fork_8": [ 0.118872553, 0.318251669, 0.817401946, 0.225490168 ],
"fork_9": [ 0.18259804, 0.2136765, 0.6335784, 0.643790841 ],
"fork_10": [ 0.05269608, 0.282303959, 0.8088235, 0.452614367 ],
"fork_11": [ 0.05759804, 0.0894935, 0.9007353, 0.3251634 ],
"fork_12": [ 0.3345588, 0.07315363, 0.375, 0.9150327 ],
"fork_13": [ 0.269607842, 0.194068655, 0.4093137, 0.6732026 ],
"fork_14": [ 0.143382356, 0.218578458, 0.7977941, 0.295751631 ],
"fork_15": [ 0.19240196, 0.0633497, 0.5710784, 0.8398692 ],
"fork_16": [ 0.140931368, 0.480016381, 0.6838235, 0.240196079 ],
"fork_17": [ 0.305147052, 0.2512582, 0.4791667, 0.5408496 ],
"fork_18": [ 0.234068632, 0.445702642, 0.6127451, 0.344771236 ],
"fork_19": [ 0.219362751, 0.141781077, 0.5919118, 0.6683006 ],
"fork_20": [ 0.180147052, 0.239820287, 0.6887255, 0.235294119 ]
}
scissors_image_regions = {
"scissors_1": [ 0.4007353, 0.194068655, 0.259803921, 0.6617647 ],
"scissors_2": [ 0.426470578, 0.185898721, 0.172794119, 0.5539216 ],
"scissors_3": [ 0.289215684, 0.259428144, 0.403186262, 0.421568632 ],
"scissors_4": [ 0.343137264, 0.105833367, 0.332107842, 0.8055556 ],
"scissors_5": [ 0.3125, 0.09766343, 0.435049027, 0.71405226 ],
"scissors_6": [ 0.379901975, 0.24308826, 0.32107842, 0.5718954 ],
"scissors_7": [ 0.341911763, 0.20714055, 0.3137255, 0.6356209 ],
"scissors_8": [ 0.231617644, 0.08459154, 0.504901946, 0.8480392 ],
"scissors_9": [ 0.170343131, 0.332957536, 0.767156839, 0.403594762 ],
"scissors_10": [ 0.204656869, 0.120539248, 0.5245098, 0.743464053 ],
"scissors_11": [ 0.05514706, 0.159754932, 0.799019635, 0.730392158 ],
"scissors_12": [ 0.265931368, 0.169558853, 0.5061275, 0.606209159 ],
"scissors_13": [ 0.241421565, 0.184264734, 0.448529422, 0.6830065 ],
"scissors_14": [ 0.05759804, 0.05027781, 0.75, 0.882352948 ],
"scissors_15": [ 0.191176474, 0.169558853, 0.6936275, 0.6748366 ],
"scissors_16": [ 0.1004902, 0.279036, 0.6911765, 0.477124184 ],
"scissors_17": [ 0.2720588, 0.131977156, 0.4987745, 0.6911765 ],
"scissors_18": [ 0.180147052, 0.112369314, 0.6262255, 0.6666667 ],
"scissors_19": [ 0.333333343, 0.0274019931, 0.443627447, 0.852941155 ],
"scissors_20": [ 0.158088237, 0.04047389, 0.6691176, 0.843137264 ]
}
Nota
Si no tiene una utilidad de clic y arrastre 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.
A continuación, use este mapa de asociaciones para cargar cada imagen de ejemplo con sus coordenadas de región (puede cargar hasta 64 imágenes en un solo 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
Deberá cambiar la ruta de acceso a las imágenes en función de dónde descargó anteriormente el repositorio de ejemplos de SDK de Foundry Tools Python.
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)
Propina
Entrenar con etiquetas seleccionadas
Opcionalmente, puede entrenar solo en un subconjunto de las etiquetas aplicadas. Es posible que quiera hacerlo si aún no ha aplicado suficientes etiquetas, pero sí tiene suficientes otros. En la llamada train_project , establezca el parámetro opcional selected_tags en una lista de las cadenas de identificador de las etiquetas que desea usar. El modelo entrena 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 acceso de predicción hasta que se publique. El código siguiente 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 predicción
Para enviar una imagen al punto de conexión de 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. A continuación, puede comprobar que la imagen de prueba (que se encuentra en <base_image_location>/images/Test) está etiquetada correctamente y que la región de detección es 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 en su lugar), es posible que desee eliminar el proyecto de detección de bifurcaciones o tijeras de este ejemplo. Una suscripción gratuita permite dos proyectos de Custom Vision.
En el sitio web de Custom Vision, ve a Proyectos y haz clic en el icono de la papelera bajo Mi nuevo Proyecto.
Pasos siguientes
Ahora ha realizado todos los pasos del proceso de detección de objetos en el código. Este ejemplo ejecuta una única iteración de entrenamiento, pero a menudo deberá entrenar y probar el modelo varias veces para que sea más precisa. En la siguiente guía se trata la clasificación de imágenes, pero sus principios son similares a la detección de objetos.
- ¿Qué es Custom Vision?
- El código fuente de este ejemplo se puede encontrar en GitHub
- Documentación de referencia del SDK