Modelo OCR de Placas Colombianas (TFLite)

¡Hola! Este repositorio te trae un modelo de IA súper compacto (TFLite) que sabe leer matrículas de carros y motos colombianas. Está hecho para funcionar de maravilla en tu celular o cualquier dispositivo pequeño.

¿Qué hace este modelo?

Imagínate que le pasas una foto de una placa, y él te dice qué texto hay ahí. Fue entrenado con muchas fotos de placas colombianas para ser muy bueno en eso.

Archivos importantes aquí:

  • crnn_plate_reader.tflite: Este es el "cerebro" del modelo. Es el archivo que usas en tu app para que lea las placas.
  • vocabulary.txt: Es como un diccionario para el modelo. Le dice qué letras y números puede reconocer. Lo necesitas para entender lo que el modelo te "dice".

¿Cómo funciona por dentro? (¡Para curiosos!)

Nuestro modelo es un "CRNN", que suena complicado pero es simple:

  1. "Ve" la placa (CNN): Primero, usa unas capas especiales (Convolutional Neural Network o CNN) para entender las formas y líneas de la placa.
  2. "Lee" la secuencia (RNN): Luego, otras capas (Bidirectional LSTM o RNN) que son buenas leyendo secuencias, juntan lo que "vio" para formar la palabra.
  3. "Adivina" la letra (Costo CTC): Al final, usa una técnica llamada CTC para adivinar las letras y números, incluso si no están perfectamente alineados en la foto. ¡Es muy inteligente!

¿Quieres usarlo en tu app móvil? ¡Paso a paso!

Aquí te explico cómo integrar este modelo en tu aplicación (Android, iOS, o similar) de forma sencilla.

1. Prepara tu proyecto

Primero, necesitas añadir TensorFlow Lite a tu app. Busca la guía oficial de TensorFlow Lite para tu plataforma (Android o iOS) para los pasos específicos de configuración. Generalmente, implica añadir una dependencia en tu archivo de configuración (build.gradle para Android o Podfile para iOS).

2. Carga los archivos del modelo

Descarga crnn_plate_reader.tflite y vocabulary.txt de este repositorio. Guarda crnn_plate_reader.tflite en la carpeta de "assets" o "raw" de tu proyecto móvil. vocabulary.txt lo puedes guardar donde te sea más cómodo para leerlo.

3. Carga el modelo en tu código

Necesitarás un Interpreter de TFLite para cargar el modelo. Aquí te doy un ejemplo conceptual (el código exacto varía según el lenguaje y plataforma):

// Ejemplo Conceptual (Android - Java)
AssetFileDescriptor fileDescriptor = getAssets().openFd("crnn_plate_reader.tflite");
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
FileChannel fileChannel = inputStream.getChannel();
long startOffset = fileDescriptor.getStartOffset();
long declaredLength = fileDescriptor.getDeclaredLength();
MappedByteBuffer tfliteModel = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);

Interpreter tflite = new Interpreter(tfliteModel);

// Cargar el vocabulario
List<String> vocabulary = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("vocabulary.txt")))) {
    String line;
    while ((line = reader.readLine()) != null) {
        vocabulary.add(line);
    }
}

4. Prepara la imagen de la placa

Antes de pasársela al modelo, la imagen de la placa debe cumplir ciertos requisitos:

  • Tamaño: Ajusta la imagen a 128 píxeles de ancho por 32 píxeles de alto.
  • Blanco y Negro (Escala de Grises): Conviértela a escala de grises. El modelo solo "ve" una capa de color.
  • Normalización: Los valores de los píxeles deben estar entre 0 y 1 (donde 0 es negro y 1 es blanco). Si tu imagen está en 0-255, divídela entre 255.0.
// Ejemplo Conceptual (Android - Java)
Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("placa_ejemplo.jpg"));
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 128, 32, true);

// Convertir a escala de grises y normalizar
ByteBuffer imgData = ByteBuffer.allocateDirect(1 * 128 * 32 * 4); // 1 imagen, 128x32, 4 bytes por float
imgData.order(ByteOrder.nativeOrder());

for (int y = 0; y < 32; y++) {
    for (int x = 0; x < 128; x++) {
        int pixel = resizedBitmap.getPixel(x, y);
        // Extraer el canal verde (aproximación a escala de grises) y normalizar
        imgData.putFloat(((pixel >> 8) & 0xFF) / 255.0f);
    }
}
// El modelo espera el formato [1, 128, 32, 1]
// En Java, a menudo se usa un array multidimensional o un ByteBuffer para esto.
float[][][][] inputArray = new float[1][128][32][1];
// ... llenar inputArray con los datos de la imagen preprocesada

5. Haz la predicción con el modelo

Ahora, pasa la imagen preparada al intérprete de TFLite para obtener la salida.

// Ejemplo Conceptual (Android - Java)
float[][][] outputArray = new float[1][16][vocabulary.size() + 1]; // [batch_size, timesteps, num_classes]
tflite.run(inputArray, outputArray);

6. Decodifica el resultado

El modelo te dará probabilidades. Necesitas convertir esos números a la secuencia de texto de la placa usando un algoritmo de decodificación CTC. El método "greedy" es el más sencillo:

// Ejemplo Conceptual (Android - Java - Decodificación CTC Greedy)
StringBuilder decodedPlate = new StringBuilder();
int lastCharIndex = vocabulary.size(); // Nuestro 'blank' token

for (int t = 0; t < 16; t++) { // Iterar sobre los 'timesteps'
    int bestCharIndex = 0;
    float maxProb = -1.0f;
    for (int c = 0; c < vocabulary.size() + 1; c++) { // +1 por el blank
        if (outputArray[0][t][c] > maxProb) {
            maxProb = outputArray[0][t][c];
            bestCharIndex = c;
        }
    }

    if (bestCharIndex != lastCharIndex && bestCharIndex < vocabulary.size()) {
        // Evitar duplicados y tokens 'blank'
        if (decodedPlate.length() == 0 || vocabulary.get(bestCharIndex).charAt(0) != decodedPlate.charAt(decodedPlate.length() - 1)) {
            decodedPlate.append(vocabulary.get(bestCharIndex));
        }
    }
    lastCharIndex = bestCharIndex;
}

String finalPlate = decodedPlate.toString();
// Opcional: limpiar la placa con expresiones regulares para formatos XXX000 o XXX00X
// (Esto ya se hizo en el notebook de entrenamiento con 'limpiar_placa')

Detalles Técnicos (Para desarrolladores)

  • Entrenado con: Placas reales de Colombia. Roboflow
  • Tecnologías: OCR API OpenAI, TensorFlow, Keras, optimizado con TFLite.
  • Máx. Caracteres: Puede reconocer hasta 7 caracteres en una placa.
  • Vocabulario: Los caracteres que conoce son: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.
  • Rendimiento: Rendimiento evaluable en el prototipo de la App en Android.

🌟 Reconocimientos y Créditos (Attribution)

El desarrollo de este modelo no hubiera sido posible sin la contribución de terceros, específicamente en el apoyo y definición de la ruta de trabajo de nuestro equipo de Hackatón.

1. Agradecimiento por el Dataset

La robustez de este modelo CRNN se basa en gran medida en la calidad y cantidad de imágenes utilizadas para su entrenamiento.

  • Fuente Principal del Dataset: El conjunto de datos de matrículas colombianas utilizado para entrenar y validar este modelo fue obtenido del repositorio público de Roboflow Universe, bajo el nombre Placas Colombia (autoría de usco-thj9e).
  • Licencia de Datos: Este dataset está regido por la licencia CC BY 4.0, la cual permite su uso, adaptación y redistribución, siempre que se cite al autor original.

📝 Citación Requerida: Si utilizas o redistribuyes este modelo o sus resultados, te instamos a mantener esta atribución al dataset de origen: "Placas Colombia" por usco-thj9e en Roboflow Universe (CC BY 4.0).

2. Agradecimiento por el Desarrollo del Modelo

Un agradecimiento especial a [Michael Leonardo Aguas] por la conceptualización, implementación, entrenamiento y optimización de este modelo TFLite CRNN para el reconocimiento óptico de caracteres de matrículas colombianas, logrando un rendimiento superior en dispositivos móviles.

Downloads last month
8
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support