Cloud Translation y Vision API para aprender vocabulario en Alemán

El aprender un nuevo idioma siempre tiene diferentes retos, uno de los primeros pasos es obtener el vocabulario. Conocer nuevas palabras nos permite comprender y describir nuestro entorno, con el tiempo logramos formar frases simples y evoluciona hasta convertirse en la puerta que nos permite hablar, aunque de manera un tanto imperfecta, al comenzar es importante aprenderlas para poder transmitir nuestras ideas y necesidades.

Sobre el idioma

Para las personas que vivimos en Latinoamérica, el Alemán no es un idioma que escuchemos o estemos habituados a tener contacto. Dark la serie de Netflix, es lo más cercano que podríamos llegar a estar y aun así, puede parecer hasta cierto punto intimidante.

Una de las claves para poder entender y tener una buen manejo del idioma, es el conocimiento y uso de los artículos. El artículo, es la pieza clave que nos permite darle sentido a lo que leemos, escribimos y hablamos.

Artículos (Traducción: En 2006 hice mi Doctorado sobre máquinas termodinámicas cuánticas autónomas...
pero la gramática alemana me mata)


Cloud Translation y Vision API

Al aprender un idioma, existen momentos y escenarios en los que necesitas descubrir una nueva palabra. Si bien existen traductores súper probados, el utilizar las herramientas ya existentes para construir soluciones a nuestras necesidades, es una de nuestras características como ingenieros.

Decidí construir una pequeña aplicación, que consumiera un servicio que me permita analizar la imagen tomada por mi celular y de esa manera enriquecer mi vocabulario en Alemán, para ello utilicé Vision API, para analizar una foto y a partir del primer resultado generar la traducción empleando Cloud Translation.

🤓 Manos a la obra!

Google Cloud, cuenta con dos servicios de reconocimiento de imágenes entre sus productos, AutoML Vision y Vision API, este último tiene la característica de brindarnos resultados a través de labels o etiquetas predefinidas, es decir, no tenemos que entrenar nosotros mismos los modelos para poder comenzar a desarrollar.

Vision API, puede resolver problemas relacionados con la detección de objetos, productos, detectar texto en imágenes entre otros. Para comenzar nuestro proyecto, crearemos un endpoint utilizando express y express-formidable, el cual se encargará de recibir un archivo y será procesado por ambas APIs.

const express = require('express');
const formidable = require('express-formidable');
const cors = require('cors');

const PORT = process.env.PORT || 8080;

const app = express();
app.use(formidable());
app.use(cors());

/*Cloud Vision API*/
//POR DEFINIR
/*Cloud Translation API*/
const translateFromImage = async (image) => {
  //AQUI IRA EL PROCESAMIENDO DE VISION API
};

app.post('/translate', async (req, res) => {
  const obj = await translateFromImage(req.files.data.path);
  return res.status(200).json(obj);
});

app.listen(PORT, () => console.log(`App listening on port ${PORT}`));

Ahora necesitamos la librería @google-cloud/vision dentro de nuestro proyecto y además tenemos que indicar el PROJECT ID correspondiente al proyecto de Google Cloud que utilizaremos, es importante recalcar que para utilizar esta API necesitas habilitar el pago dentro de tu proyecto. Puedes leer más sobre requerimientos que necesitas en la documentación oficial.

...
/*Cloud Vision API && Cloud Translation API*/
const vision = require('@google-cloud/vision');
const PROJECT_ID = process.env.projectID || 'map-visualisations';
...

En este punto se implementa el código correspondiente a la función translateFromImage, con el fin de obtener las etiquetas de la imagen, es importante tener en cuenta que estas etiquetas se encuentran almacenadas dentro de un Array.

const translateFromImage = async (image) => {
  const client = new vision.ImageAnnotatorClient();
  const [result] = await client.labelDetection(image);
  //Regresamos la primera opción
  return result.labelAnnotations[0].description;
};

Con el contenido de la imagen etiquetado correctamente, podemos proceder a realizar la traducción utilizando Cloud Translation, usaremos la librería @google-cloud/translate.

...
/*Cloud Translation API*/
const {TranslationServiceClient} = require('@google-cloud/translate');
...

Modificando la función translateFromImage, agregaremos dos parámetros y se realizará la petición al servicio translateText, el parámetro source nos indica el idioma de origen, en este caso “en” correspondiente al idioma inglés y “de” correspondiente al idioma Alemán.

const translateFromImage = async (image, source = 'en', target = 'de') => {
  const client = new vision.ImageAnnotatorClient();
  const translationClient = new TranslationServiceClient();

  const [result] = await client.labelDetection(image);
  const request = {
    parent: `projects/${PROJECT_ID}/locations/global`,
    contents: [`the ${result.labelAnnotations[0].description}`],
    mimeType: 'text/plain',
    sourceLanguageCode: source,
    targetLanguageCode: target,
  };

  const [response] = await translationClient.translateText(request);
  const text = response.translations[0].translatedText;
  const [article, substantive] = text.split(' ');
  return { article, substantive };
};

Y listo! Tenemos nuestro servicio construido, que traduce imágenes utilizando unas cuantas líneas de código, puedes revisar el archivo final directamente en este repositorio 👈.

Interfaz con expo.io

Platicando con mi buen amigo Uriel Miranda, me comentó sobre el uso de expo.io para la creación de aplicaciones. Es un Framework, que nos permite crear aplicaciones con React, con la bondad de tener varios componentes que interactuan de manera sencila con el hardware del celular, como lo es la cámara. Puedes encontrar la documentación oficial en el siguiente link expo.io 👈.

Para ver el código completo de la aplicación, puede visitar el repositorio artikelausein_bild en Github.

El componente encargado de conectarse con el servidor y obtener la data, se ve de la siguiente manera:

const URL = 'TU_ENDPOINT_AQUI';

async function translate(imageURI: string) {
  const formData = new FormData();
  formData.append('data', {
    uri: imageURI,
    name: 'photo',
    type: 'image/jpg',
  });

  return await fetch(URL + '/translate', {
    method: 'POST',
    body: formData,
  }).then(async (response) => {
    return response.json();
  });
}

export default {
  translate,
};

Y dado que el artículo es importante para este caso de aprendizaje, resaltamos el artículo de la palabra de la siguiente forma:

<TouchableWithoutFeedback onPressIn={reset}>
  <Text style={styles.resultTranslation}>
    <Text style={{ backgroundColor: articleColors[state.article].color }}>
      {state.article}
    </Text>
    {state.substantive}
  </Text>
</TouchableWithoutFeedback>

Podemos visualizar los resultados como se muestra en las siguientes imagenes:

Resultados con artículos Resultados con artículos

Conclusiones

La construcción de esta aplicación me ha permitido mejorar mi vocabulario al explorar lo que me rodea. Me hizo comprender más sobre los diferentes servicios de Google como lo son Vision API y Cloud Translate, si bien son servicios que tienen una cuota, brindan a empresas y desarrolladores poderosas herramientas para traer sus ideas a la realidad en forma de productos.

Seguiré mejorando la aplicación y si te interesa contribuir puedes enviar un Pull Request.

Acá te comparto el video del funcionamiento de la aplicación:

Video obteniendo artículos Video obteniendo artículos