Views
No views yet
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".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).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.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):1// Ejemplo Conceptual (Android - Java)
2AssetFileDescriptor fileDescriptor = getAssets().openFd("crnn_plate_reader.tflite");
3FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
4FileChannel fileChannel = inputStream.getChannel();
5long startOffset = fileDescriptor.getStartOffset();
6long declaredLength = fileDescriptor.getDeclaredLength();
7MappedByteBuffer tfliteModel = fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
8
9Interpreter tflite = new Interpreter(tfliteModel);
10
11// Cargar el vocabulario
12List<String> vocabulary = new ArrayList<>();
13try (BufferedReader reader = new BufferedReader(new InputStreamReader(getAssets().open("vocabulary.txt")))) {
14 String line;
15 while ((line = reader.readLine()) != null) {
16 vocabulary.add(line);
17 }
18}128 píxeles de ancho por 32 píxeles de alto.0 y 1 (donde 0 es negro y 1 es blanco). Si tu imagen está en 0-255, divídela entre 255.0.1// Ejemplo Conceptual (Android - Java)
2Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open("placa_ejemplo.jpg"));
3Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 128, 32, true);
4
5// Convertir a escala de grises y normalizar
6ByteBuffer imgData = ByteBuffer.allocateDirect(1 * 128 * 32 * 4); // 1 imagen, 128x32, 4 bytes por float
7imgData.order(ByteOrder.nativeOrder());
8
9for (int y = 0; y < 32; y++) {
10 for (int x = 0; x < 128; x++) {
11 int pixel = resizedBitmap.getPixel(x, y);
12 // Extraer el canal verde (aproximación a escala de grises) y normalizar
13 imgData.putFloat(((pixel >> 8) & 0xFF) / 255.0f);
14 }
15}
16// El modelo espera el formato [1, 128, 32, 1]
17// En Java, a menudo se usa un array multidimensional o un ByteBuffer para esto.
18float[][][][] inputArray = new float[1][128][32][1];
19// ... llenar inputArray con los datos de la imagen preprocesada1// Ejemplo Conceptual (Android - Java)
2float[][][] outputArray = new float[1][16][vocabulary.size() + 1]; // [batch_size, timesteps, num_classes]
3tflite.run(inputArray, outputArray);1// Ejemplo Conceptual (Android - Java - Decodificación CTC Greedy)
2StringBuilder decodedPlate = new StringBuilder();
3int lastCharIndex = vocabulary.size(); // Nuestro 'blank' token
4
5for (int t = 0; t < 16; t++) { // Iterar sobre los 'timesteps'
6 int bestCharIndex = 0;
7 float maxProb = -1.0f;
8 for (int c = 0; c < vocabulary.size() + 1; c++) { // +1 por el blank
9 if (outputArray[0][t][c] > maxProb) {
10 maxProb = outputArray[0][t][c];
11 bestCharIndex = c;
12 }
13 }
14
15 if (bestCharIndex != lastCharIndex && bestCharIndex < vocabulary.size()) {
16 // Evitar duplicados y tokens 'blank'
17 if (decodedPlate.length() == 0 || vocabulary.get(bestCharIndex).charAt(0) != decodedPlate.charAt(decodedPlate.length() - 1)) {
18 decodedPlate.append(vocabulary.get(bestCharIndex));
19 }
20 }
21 lastCharIndex = bestCharIndex;
22}
23
24String finalPlate = decodedPlate.toString();
25// Opcional: limpiar la placa con expresiones regulares para formatos XXX000 o XXX00X
26// (Esto ya se hizo en el notebook de entrenamiento con 'limpiar_placa')7 caracteres en una placa.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.usco-thj9e).📝 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" porusco-thj9een Roboflow Universe (CC BY 4.0).