Clasifique imágenes en Android con TensorFlow Lite y Azure Custom Vision

La clasificación de imágenes permite que nuestras aplicaciones Xamarin reconozcan objetos en fotografías.

Cada vez más común es la capacidad de tomar una foto y reconocer su contenido. Podemos observar esto en nuestras aplicaciones bancarias cuando hacemos un depósito móvil, en aplicaciones fotográficas al agregar filtros y en aplicaciones HotDog para determinar si nuestra comida es un hot dog.

Gracias al servicio Azure Custom Vision, no necesitamos aprender algoritmos complejos de aprendizaje automático para implementar la clasificación de imágenes.

En este artículo, veremos cómo implementar la clasificación de imágenes con el servicio Azure Custom Vision , TensorFlow Lite (plataforma de aprendizaje automático de código abierto) yXamarin, Android .


Nota: Para Xamarin.iOS, también podemos usar el servicio Azure Custom Vision con CoreML , pero es mejor que lo guardemos para otro artículo.

imagen

Bibliotecas de clasificación de imágenes


Utilizaremos el servicio Azure Custom Vision y TensorFlow Lite para implementar nuestra clasificación de imágenes.

1. Servicio Azure Custom Vision


El servicio Azure Custom Vision simplifica la creación y la capacitación de un modelo de aprendizaje automático: no requiere experiencia con Inteligencia Artificial (AI) o Aprendizaje Automático (ML).

Usando el portal web del servicio Custom Vision , podemos hacer lo siguiente sin escribir ningún código AI / ML:

  1. Descargar imagen de entrenamiento
  2. Etiquetas de marca / Etiquetas de objeto (s) en la imagen
  3. Repita (el modelo mejora con más datos de entrenamiento)
  4. Eso es todo: ¡Custom Vision se encarga del resto!

2. TensorFlow Lite


TensorFlow Lite es una plataforma de aprendizaje automático de código abierto que nos permite usar TensorFlow en IoT y dispositivos móviles.

TensorFlow Lite y TensorFlow están disponibles en código abierto en GitHub .

Implementación de clasificación de imágenes con Azure + Xamarin.Android


Una aplicación completa de clasificación de imágenes de muestra está disponible en GitHub .

1. Entrenamiento modelo


Usando el portal web del servicio Custom Vision , primero entrenamos modelos de clasificación de imágenes.

1. En el portal web del servicio Custom Vision, haga clic en Nuevo proyecto

imagen

2. En la ventana Crear nuevo proyecto , configure los siguientes parámetros:

  • Nombre: XamarinImageClassification
  • Descripción: Identificar objetos en imágenes
  • Recurso: [Crear un nuevo recurso]
  • Tipo de proyecto: Clasificación
  • Tipos de clasificación: Multilabel (múltiples etiquetas por imagen)
  • Dominios: General (compacto)
  • Capacidades de exportación: plataformas básicas

3. En la ventana Crear nuevo proyecto , haga clic en Crear proyecto

4. En la ventana XamarinImageClassification, haga clic en Agregar imágenes

5. Seleccione las imágenes que contienen el objeto para identificación

6. En la ventana Cargar imagen , agregue una etiqueta
Nota: en este ejemplo, estamos trabajando con imágenes de hongos

7. En la ventana Imagen cargar haga clic en Cargar
Nota: siga cargando imágenes hasta que tenga al menos 5 imágenes para cada etiqueta

imagen

8. En la ventana XamarinImageClassification en la esquina superior derecha de la ventana, haga clic en el botón Modelo de tren (imagen verde de engranajes)

9. En la ventana Elegir tipo de entrenamiento , seleccione Entrenamiento rápido

10. En la ventana Elegir tipo de entrenamiento , seleccione Tren

imagen

2. Exportar un modelo entrenado del servicio Azure Custom Vision


Ahora que hemos entrenado nuestro modelo, exportémoslo para usarlo en nuestra aplicación móvil .

Esto nos permitirá usar el modelo sin conexión a Internet, lo que garantizará la mejor privacidad para el usuario, ya que sus fotos nunca saldrán del dispositivo móvil.

Para exportar nuestro modelo, hagamos lo siguiente:

1. En la ventana XamarinImageClassifcation en la parte superior de la página, seleccione la pestaña Rendimiento

2. En la pestaña Rendimiento , haga clic en el botón Exportar (flecha hacia abajo)

3. En la ventana Elija su plataforma , seleccione TensorFlow

imagen

4. En la lista desplegable Elija su plataforma , seleccione TensorFlow Lite

5. En la ventana Elija su plataforma , seleccione Descargar

imagen

3. Importe TensorFlow Lite a nuestra aplicación Xamarin.Android


1. Instale el paquete NuGet apropiado en nuestro proyecto Xamarin.Android
Nota: Este paquete NuGet es un proyecto de código abierto creado por el equipo de Xamarin en Microsoft. Contiene enlaces C # para la biblioteca original de TensorFlow Lite , lo que permite su uso en nuestra aplicación Xamarin.Android

2. Descomprima el modelo exportado que descargamos del portal web del servicio Custom Vision.
Nota: dentro del archivo zip se encuentran labels.txt y model.tflite :

  • labels.txt contiene etiquetas de imagen creadas durante la preparación para la capacitación en el sitio web de Custom Vision
  • models.tflite es el modelo de aprendizaje automático que utilizamos para nuestros pronósticos.

3. En Visual Studio, en el proyecto Xamarin.Android, haga clic con el botón derecho en la carpeta Activos

4. En el menú emergente, seleccione AgregarElemento existente ...

5. En el menú Agregar elemento existente , seleccione ambos archivos recientemente desempaquetados:

  • modelos.tflite
  • etiquetas.txt

6. En Visual Studio, en Xamarin.AndroidAssets , haga clic con el botón derecho en labels.txt

7. En el menú emergente, seleccione Propiedades

8. En la ventana Propiedades , seleccione Build ActionAndroid Asset

9. En Visual Studio, en Xamarin.AndroidActivos , haga clic con el botón derecho en models.tflite

10. En el menú emergente, seleccione Propiedades

11. En la ventana Propiedades , seleccione Crear acciónActivo Android

imagen

4. Implementación del código de clasificación de imágenes para Xamarin.Android


Ahora que hemos importado el modelo, es hora de escribir algo de código.

Como recordatorio, una aplicación de clasificación de imágenes de muestra completamente terminada está disponible en GitHub .

En el proyecto Xamarin.Android , agregue ImageClassifcationModel.cs y TensorflowClassifier.cs :

ImageClassificationModel.cs


public class ImageClassificationModel 
{ 
    public ImageClassificationModel(string tagName, float probability) 
    { 
        TagName = tagName; 
        Probability = probability; 
    } 
   
    public float Probability { get; } 
    public string TagName { get; } 
}

TensorflowClassifier.cs


using System.Collections.Generic;
using System.IO;
using System.Linq;
using Android.App;
using Android.Graphics;
using Java.IO;
using Java.Nio;
using Java.Nio.Channels;

public class TensorflowClassifier
{
    //FloatSize     4,        4 
    const int FloatSize = 4;
    //PixelSize -     3,        : ,   .
    const int PixelSize = 3;

    public List<ImageClassificationModel> Classify(byte[] image)
    {
        var mappedByteBuffer = GetModelAsMappedByteBuffer();
        var interpreter = new Xamarin.TensorFlow.Lite.Interpreter(mappedByteBuffer);

        //   ,       
        var tensor = interpreter.GetInputTensor(0);
        var shape = tensor.Shape();

        var width = shape[1];
        var height = shape[2];

        var byteBuffer = GetPhotoAsByteBuffer(image, width, height);

        // StreamReader    labels.txt
        var streamReader = new StreamReader(Application.Context.Assets.Open("labels.txt"));

        // labels.txt  List<string>
        var labels = streamReader.ReadToEnd().Split('\n').Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();

        //     Java.Lang.Object,    Xamarin.TensorFlow.List.Interpreter.
        var outputLocations = new float[1][] { new float[labels.Count] };
        var outputs = Java.Lang.Object.FromArray(outputLocations);

        interpreter.Run(byteBuffer, outputs);
        var classificationResult = outputs.ToArray<float[]>();

        // classificationResult     ,  ,     
        var classificationModelList = new List<ImageClassificationModel>();

        for (var i = 0; i < labels.Count; i++)
        {
            var label = labels[i]; classificationModelList.Add(new ImageClassificationModel(label, classificationResult[0][i]));
        }

        return classificationModelList;
    }

    // model.tflite  Java.Nio.MappedByteBuffer,    Xamarin.TensorFlow.Lite.Interpreter.
    private MappedByteBuffer GetModelAsMappedByteBuffer()
    {
        var assetDescriptor = Application.Context.Assets.OpenFd("model.tflite");
        var inputStream = new FileInputStream(assetDescriptor.FileDescriptor);

        var mappedByteBuffer = inputStream.Channel.Map(FileChannel.MapMode.ReadOnly, assetDescriptor.StartOffset, assetDescriptor.DeclaredLength);

        return mappedByteBuffer;
    }

    //     TensorFlow
    private ByteBuffer GetPhotoAsByteBuffer(byte[] image, int width, int height)
    {
        var bitmap = BitmapFactory.DecodeByteArray(image, 0, image.Length);
        var resizedBitmap = Bitmap.CreateScaledBitmap(bitmap, width, height, true);

        var modelInputSize = FloatSize * height * width * PixelSize;
        var byteBuffer = ByteBuffer.AllocateDirect(modelInputSize);
        byteBuffer.Order(ByteOrder.NativeOrder());

        var pixels = new int[width * height];
        resizedBitmap.GetPixels(pixels, 0, resizedBitmap.Width, 0, 0, resizedBitmap.Width, resizedBitmap.Height);

        var pixel = 0;

        //     Java.Nio.ByteBuffer
        for (var i = 0; i < width; i++)
        {
            for (var j = 0; j < height; j++)
            {
                var pixelVal = pixels[pixel++];

                byteBuffer.PutFloat(pixelVal >> 16 & 0xFF);
                byteBuffer.PutFloat(pixelVal >> 8 & 0xFF);
                byteBuffer.PutFloat(pixelVal & 0xFF);
            }
        }

        bitmap.Recycle();

        return byteBuffer;
    }
}

¡Eso es todo! Ahora podemos pasar la imagen a TensorflowClassifier.Classify para obtener el ImageClassificationModel .

Materiales para ulterior estudio


Mira los enlaces a continuación:


All Articles