Publicado el Deja un comentario

Primeros pasos con OpenCV

En este post, vamos a hablar sobre algunos conceptos fundamentales para iniciarse a OpenCV y al procesamiento de imágenes. ¡Comencemos!

¿Qué es una imagen bajo una perspectiva computacional?

Todos podríamos dar una definición más o menos buena de lo que es una imagen. Pero, ¿de qué forma puede un ordenador representar una imagen?

Imágenes en escala de grises

Comencemos con el ejemplo más sencillo, el de una imagen monocanal, como puede ser una imagen en escala de grises. Este tipo de imágenes, a nivel computacional, se representan como una matriz de números, sin más complicaciones. Estas matrices son bidimensionales, ya que una dimensión será el ancho y, la otra dimensión, será el alto. En cada una de las posiciones de esa matriz, hay un número que representa el nivel de intensidad de gris de la imagen en ese punto concreto.

Generalmente, la matriz de una imagen suele estar formada por números enteros o números decimales. Con frecuencia, el nivel de intensidad de cada píxel suele representarse con una secuencia binaria de 1 byte, es decir, 8 bits. Esto significa que cada píxel de la imagen puede tomar 28 valores diferentes, lo que hace un total de 256 niveles de gris representables. Cuando trabajamos con números enteros, el rango de valores estará entre el 0 y el 255, donde 0 representa el nivel de intensidad mínimo (es decir, el negro) y el 255 representa el máximo nivel de intensidad posible (es decir, el blanco). Entre 0 y 255 se encuentra una gama de grises. Comúnmente, estos 256 diferentes valores son más que suficientes para poder mostrar imágenes que tengan una apariencia realista bajo nuestra percepción.

Sin embargo, es muy común que se utilice números decimales para representar el nivel de gris de un punto determinado en una imagen. En lugar de tener un rango entre 0 y 255, este rango se sitúa entre 0 y 1. Entonces, ¿cómo es posible representar los niveles de gris de una imagen con un valor entre 0 y 1? Lo que se hace es dividir este intervalo real en 256 particiones. De esta forma, cada partición tendría un tamaño de 1/255 = 0.0039 (se divide entre 255 para que el valor decimal 1 se corresponda con el nivel de intensidad 255).

De este modo, el valor de intensidad 0 estaría representado igualmente por 0, el valor de intensidad 1 estaría representado por el número 0.0039, el valor de intensidad 2 estaría representado por 0.0078.. y así sucesivamente. Hay ocasiones en las que incluso se establece un rango de valores entre el -1 y el 1. Y te preguntarás, ¿por qué se escogen los rangos de números reales? Esto es debido, especialmente, a que esos rangos tienen algunas propiedades estadísticas interesantes (nos permite disponer de unas muestras de datos normalizadas). Para ciertos algoritmos, podría ser indispensable que los datos de entrada estén normalizados y de ahí esta relevancia.

Imágenes en color

Una vez visto el caso para las imágenes en escala de grises, la extrapolación de estas ideas al dominio de las imágenes en color es muy sencilla. Si las imágenes en escala de grises están representadas por una matriz bidimensional, las imágenes en color se representan con una matriz tridimensional. En este caso, además de tener las dimensiones de ancho y alto, existe una tercera, que se corresponde con el canal de color. Generalmente, estas imágenes se encuentran representadas por un modelo de color que se conoce por sus siglas RGB (red, green, blue). Cada píxel de la imagen está representado por tres componentes. Cada una de esas componentes indica, respectivamente, la cantidad de rojo, azul y verde que contiene el punto.

Por decirlo de alguna forma, cada imagen RGB está representada por tres matrices bidimensionales donde la primera representa el canal rojo, la segunda el canal azul y, la tercer, el canal verde. Cada componente de color está representado por una secuencia de 1 byte, es decir, 8 bits, lo cual hace un total de 32 bits que permiten representar 232 = 4294967296 colores diferentes. Esta gama de colores es suficiente para que las imágenes tengan un resultado con apariencia realista.

En ocasiones, se utiliza el modelo de color RGBA que incluye un cuarto canal, donde se representa la opacidad del píxel. Suponiendo un rango entre 0 y 255, el valor 0 representa un píxel totalmente transparente y, el 255, representa un píxel totalmente opaco. Existe una gama de opacidades entre estos valores extremos. Este tipo de imágenes, por tanto, permite representar el mismo número de colores diferentes que el modelo RGB y, además, permite representar 256 niveles distintos de opacidad, para cada píxel. Generalmente se comienza hablando sobre el modelo de color RGB, pero también existen otros como el HSV, el HSL o el LUV, por ejemplo, donde cada canal representa una cualidad del color concreta.

Trabajar con imágenes en OpenCV: primeros pasos

Una vez que hemos visto la teoría de cómo se representa una imagen, pasemos directamente a la implementación práctica de las funcionalidades básicas. El primer paso, antes de hacer cualquier cosa con una imagen, es leerla y cargarla en memoria. Pues esto es lo que vamos a hacer a continuación.

La lectura de imágenes en OpenCV es muy sencilla. Simplemente, se debe utilizar la función «imread()» disponible en la librería especificando la ruta del fichero donde se encuentra almacenada la imagen. Por ejemplo, vamos a leer el logo de la página y vamos a jugar un poquito con él. Está almacenado en un fichero que se llama «input.png» y está situado en la misma carpeta donde tenemos el script. Después, vamos a mirar qué tamaño tiene la matriz obtenida al leer dicha imagen.

A la salida tenemos «(500, 500, 3)». ¿Qué quiere decir esto? Quiere decir que la imagen tiene una resolución de 500 x 500 y tres canales de color. Como por defecto OpenCV lee en RGB y no hemos especificado ningún argumento al leer la imagen, este será el modelo de color utilizado. Sin embargo, ten en cuenta una cosa que, por alguna razón, OpenCV representa los canales con el orden contrario, así que en lugar de tener un RGB va a ser un BGR. Es decir, que el primer canal de color se corresponderá con el azul, el segundo con el verde y el tercero con el rojo. Es un poco lioso, per decidieron implementarlo así.

¿Qué podemos hacer con esta image? Lo cierto es que podemos hacer todo lo que se nos ocurra, pero vamos a por lo más básico. Por ejemplo, ¿cómo hago para coger solo un canal de color? Esto es muy sencillo, sabiendo manejar los índices de Python. En el código de más abajo se puede ver un ejemplo de código extrayendo, separadamente, los tres canales de color.

Para visualizar las imágenes de los tres canales, se puede utilizar la función «imwrite» de la librería OpenCV, que guarda el contenido de una matriz en un fichero. Ese fichero se llamará como le especifiquemos en el primer argumento. Los resultados que se obtienen son los que se pueden observar a continuación.

Si más tarde miramos el tamaño de la matriz de la imagen para un único canal (con la secuencia «print(np.shape(blue_channel))» para el canal azul, por ejemplo), obtendremos para los tres casos «(500, 500)». Es decir, como resultado tendremos una imagen monocanal en escala de grises que, a su vez, representa a un único canal de la imagen original en color. Evidentemente, de esta forma tendríamos una imagen en escala de grises por cada canal de color, en lugar de tener toda la información integrada en una única imagen.

Existen algunas técnicas para convertir una imagen en color a escala de grises integrando toda la información. El método más simple es quizá el de promediado. Es decir, si R, G y B representan la matriz de la imagen para cada canal de color y Gray la imagen en escala de grises final, la operación a llevar a cabo sería Gray = (R + G + B)/3. Pero esta técnica presenta un problema y es que nuestra capacidad de percepción nos permite distinguir una mayor cantidad de gamas de verde que de rojo y azul, por ejemplo. Esto significa que, de alguna forma, debemos darle más peso al color verde a la hora de obtener la representación en escala de grises de la imagen original en color.

Para ello, en lugar de utilizar una media aritmética normal, se realiza una media ponderada, donde se le da un peso determinado a cada canal de color. Este peso que se le da a cada uno de los canales se ha obtenido por medio de estudios científicos, resultando en la siguiente expresión (teniendo la misma notación que antes): Gray = 0.3 * R + 0.59 * G + 0.11 * B. Por lo general, las librerías de procesamiento de imágenes deberían incluir métodos para la conversión directa entre RGB y escala de grises o viceversa. Del mismo modo, también suelen disponer de métodos que permiten cambiar entre diferentes espacios de color (por ejemplo, entre RGB y HSV).

A modo de ejemplo, vamos a ilustrar diferentes formas de hacer lo mismo… aunque solo sea por una cuestión de gimnasia mental, para que así te vayas acostumbrando a manejar la librería y el lenguaje con más soltura. Comenzamos por la estrategia de hacer las operaciones de forma manual. Suponiendo que continuamos con las variables que habíamos obtenido con el código anterior, se haría de la siguiente forma:

Para visualizar los resultados, podemos utilizar las funciones que nos permiten guardar imágenes en un fichero. En este caso, utilizamos el método «imwrite()» de la librería de OpenCV.

Los resultados que se obtienen después de haber ejecutado este código son los siguientes.

Como ves, en esta sección te hemos enseñado a utilizar las funciones más básicas para trabajar con imágenes en OpenCV. Además, hemos realizado algunas operaciones muy básicas con ellas y hemos aprendido cosas fundamentales sobre las imágenes digitales. Vamos poco a poco incrementando el conocimiento sobre este interesante ámbito. ¡Nos vemos en el próximo post!

Publicado el Deja un comentario

¿Cómo segmentar una imagen utilizando contornos activos con Scikit-Image en Python?

Los contornos activos son un grupo de algoritmos que permiten realizar la segmentación de objetos de interés dentro de una imagen. Esto se consigue por medio de una curva denominada spline, cuya representación matemática permite que tenga una enorme flexibilidad. Esta flexibilidad es muy interesante para aproximar contornos de objetos que sean muy complejos. A menudo, a estas curvas de contornos activos se les denomina snakes.

Descripción del proceso de segmentación

En primer lugar, se inicializa una curva paramétrica en un punto determinado (que se puede fijar manualmente) y se definen sus valores iniciales. Esto, básicamente, nos permitirá determinar dónde queremos que se sitúe el contorno activo y las características de forma que deseamos que tenga.

En segundo lugar, se determina cómo queremos que se comporte el snake. Por decirlo de alguna forma, vamos a coger el snake, vamos a «soltarlo», dejar que busque el contorno deseado y que poco a poco se vaya ajustando. Este proceso de ajuste será iterativo, lo cual quiere decir que, si los parámetros que hemos definido son adecuados para el problema, el snake se irá aproximando cada vez más al contorno del objeto de interés a lo largo de las iteraciones. Para definir ese comportamiento, debemos especificar dos funciones de lo que denominamos como energía.

  • Energía interna: se refiere a la flexibilidad que queremos darle a la curva.
  • Energía externa: se refiere a características de la imagen que son de interés. Por medio de este valor de energía, le decimos al snake dónde está el contorno para conseguir que se aproxime lo máximo posible a él. Un ejemplo de energía externa podría ser la información de bordes o líneas de la imagen.

Para ajustar el modelo al contorno deseado, se plantea un problema de optimización donde se busca minimizar los valores de energía. Para llevar a cabo esa minimización, primero se realiza una suma ponderada de ambos valores (lo que se conoce como energía total). Con esta suma ponderada, se controla si se desea otorgar un mayor peso a la energía externa o a la interna, según sea el caso. Lo más común, es que haya que probar varios valores y ver qué conjunto de ellos resuelve mejor el problema.

Snakes en Scikit-Image

Una vez que hemos visto un poco de la teoría sobre los snakes, vamos a pasar directamente a ver cómo se implementa su uso en un problema práctico utilizando, en este caso, el lenguaje Python con la ayuda de la librería de Scikit-Image. Para ejemplificarlo con un caso sencillo y que funcione relativamente bien de forma bastante directa, vamos a tomar como referencia la siguiente imagen.

Este ejemplo será fácil de segmentar, ya que es fácil distinguir el objeto de interés (la TIerra) del fondo de la imagen

A continuación, se encuentra todo el código para poder segmentar una imagen de ejemplo.

Vamos a explicar paso a paso qué es lo que se hace en este código.

En primer lugar, se importan las librerías necesarias

En segundo lugar, especificamos los parámetros para inicializar el snake

En este caso, hemos decidido inicializar el snake como un círculo, que debe contener totalmente el objeto de interés. La imagen en cuestión, tiene una resolución de 300 x 300, por lo que un círculo de 150 píxeles de radio es más que suficiente para conseguirlo. Por otra parte, el centro del snake coincidirá exactamente con el centro de la imagen, el punto (150, 150). Además, como otro parámetro del snake, la curva estará formada por 350 puntos. Para crear el círculo, se utiliza la función «linspace()» de Numpy. Esto se almacena en una variable «init» que podrá ser utilizada como forma inicial del snake para el proceso de segmentación.

En tercer lugar, se lee la imagen, se aplica la función de contornos activos y se muestra el resultado

Leemos la imagen con la función «imread()» de Scikit-Image y almacenamos el contenido de esa imagen en una matriz de Numpy. Se lo pasamos a la función «active_contour()» junto con el «init» (es decir, la forma inicial del snake) y otra serie de parámetros que resultará interesante ajustar para modificar el comportamiento del algoritmo.

  • alpha: determina la magnitud con la que queremos que el snake se contraiga.
  • beta: determina la suavidad de la curva.
  • w_line: determina el peso que se le quiere dar a la información de las líneas de la imagen en el valor de energía total.
  • w_edge: determina el peso que se le quiere dar a la información de bordes en el valor de energía total.
  • max_iterations: especifica el número máximo de iteraciones en las que el snake podrá ajustarse.

Por último, con las funciones de Matplotlib, se podrá mostrar el resultado. Con los parámetros elegidos, obtendremos algo como lo que se puede ver a continuación.

La curva verde es el contorno inicial del snake, mientras que la curva roja es el resultado final del proceso de segmentación con el modelo deformable. Como se puede observar, el contorno rojo se ajusta bastante bien al objeto de interés, lo cual es exactamente lo que estábamos buscando.

Eso sí, aunque en este caso los resultados sean muy buenos, no te esperes que siempre ocurra así. Esta imagen es muy fácil de segmentar (incluso con otras técnicas más básicas que los modelos deformables) pero lo más seguro es que, en el caso de los objetos de la vida real, no sea ni mucho menos tan sencillo de conseguir. De hecho, si no consigues buenos resultados probando con una gran cantidad de conjuntos de parámetros, lo más probable es que los modelos deformables no sean el mejor método para el problema particular que estás tratando.

Publicado el Deja un comentario

¿En qué consiste la segmentación de imágenes?

En la lección de hoy, vamos a aprender en qué consiste la segmentación de imágenes, una de las tareas de mayor importancia dentro del contexto de la visión artificial, con un punto de vista sencillo, para que sea fácil de entender.

¿Cuál es el objetivo de la segmentación de imágenes?

En visión artificial, cada problema tiene unos objetivos muy concretos asociados y, como tal, los métodos tienen que centrarse lo máximo posible en esos objetivos y deshacerse de todo lo que no importa.

Por ejemplo. Imagínate que queremos desarrollar un método automático que sea capaz de tomar imágenes del tráfico en una ciudad para localizar y contar los coches que hay en ellas. Como la realidad es muy compleja, estas imágenes van a estar plagadas de cosas que no nos interesan: asfalto, señales, líneas pintadas, edificios, peatones, farolas, semáforos, el cielo, aves que pasan por la escena en un momento dado…

Para localizar los coches en esta imagen sería interesante eliminar toda la información que carece de relevancia en este problema: los árboles, las señales, los semáforos, la carretera, las líneas… y centrarse en lo importante.

Igual que para nosotros sería mucho más fácil localizar y contar los coches teniendo una escena donde solo visualizamos lo importante y descartamos todo lo demás, para los métodos automáticos esto funciona exactamente de la misma forma.

¿Cómo se lleva a cabo la segmentación de imágenes?

Segmentar imágenes no es, ni mucho menos, una tarea sencilla. Es muy fácil de probar en ejemplos artificiales (como, por ejemplo, un cuadrado blanco sobre un fondo negro) pero no existe un método que funcione bien para segmentar en cualquier problema que se nos plantee.

Por una parte, teniendo un problema muy concreto como es el de localizar los coches en las imágenes, un método de segmentación no va a funcionar bien en todas ellas. Esto es debido a que la realidad es muy compleja y a que las imágenes no se pueden sacar de cualquier forma (muchas de ellas podrían no ser útiles para resolver el problema en cuestión).

Por otra parte, un método que funciona muy bien para segmentar coches en imágenes, podría no servir para otra tarea diferente como, por ejemplo, segmentar a los peatones. ¿Y cuál es la forma de saber cuál es el mejor método para resolver la tarea? Básicamente, conocer a fondo la gran variedad de posibles estrategias que existen para probarlas y ver cuál de ellas da mejores resultados.

Por tanto, a la pregunta de «¿cómo se lleva a cabo la segmentación en imágenes?», la respuesta es un gran DEPENDE. No queda más remedio que aprenderse las principales técnicas que existen e ir probando con todas ellas… pero para eso estamos. Vamos a ver algunas de las técnicas de segmentación más conocidas.

Métodos de segmentación de imágenes

En esta lista, vamos a repasar algunos de los principales métodos de segmentación de imágenes que se utilizan comúnmente en la literatura.

Segmentación basada en información de histograma (umbralización)

Estos primeros métodos de segmentación trabajan sobre el histograma de las imágenes. Aquí destacamos la umbralización. De una forma muy simple, esta estrategia, en su significado más fundamental, consiste en establecer un valor de nivel de gris como umbral. Este umbral nos servirá para dividir la imagen en dos clases: una clase que se corresponde con los píxeles del objeto de interés y otra clase que se corresponde con todo lo demás, es decir, lo que no nos interesa. Con el ejemplo de antes, los coches serían el objeto de interés y, todo lo demás, sería la información que no nos interesa, lo que comúnmente llamamos fondo.

¿Cómo logramos la división de la imagen en clases?

Una vez que tenemos el valor umbral establecemos un criterio… por ejemplo: todo lo que está por encima de mi valor umbral será considerado como objeto y, todo lo que esté por debajo, será fondo. Una vez que tenemos esto, como resultado de este procesamiento se obtendrá una imagen binaria. Por lo general, para representar los píxeles de objeto se suele utilizar la intensidad de gris máxima (255, que se corresponde con el blanco) y, para representar el fondo, se suele utilizar la intensidad de gris mínima (0, que se corresponde con el negro).

¿Qué umbral se debe utilizar?

Este es otro de los parámetros a controlar dentro del método. El valor umbral óptimo para resolver el problema no lo conocemos. Es por ello que habrá que probar una serie de diferentes valores y ver con cual de ellos se segmenta mejor.

Es cierto, por otra parte, que existen métodos de segmentación que son capaces de obtener un valor umbral de forma automática. Sin embargo, esto no garantiza que la segmentación que vayas a obtener sea de mayor calidad que la que podrías obtener experimentando con los valores de un umbral seleccionado de forma manual. Uno de estos métodos es el algoritmo de Otsu.

¿Cómo se implementa la Umbralización a un nivel más técnico?

La segmentación utilizando información de histograma suele hacerse utilizando imágenes de un solo canal de color, es decir, en escala de grises. Sin embargo, te preguntarás… ¿entonces cómo hago esto en imágenes a color? Por ejemplo, en RGB tenemos tres canales de color… parece que este planteamiento no funciona.

En estos casos, el procedimiento a seguir es un poco distinto. Existen principalmente dos opciones: convertir la imagen original en color a escala de grises o seleccionar un solo canal de esa imagen original. Por supuesto, si la imagen ya está en escala de grises, no hay nada que hacer en este paso.

Más tarde, la imagen monocanal es sometida a la umbralización. Las imágenes no son más que matrices de números de dos dimensiones (la altura y la anchura), en el caso de que tengan un único canal de color. La umbralización sencillamente se encargará de analizar píxel a píxel el valor de nivel de gris, diciendo «como este píxel es superior al umbral especificado, le voy a asignar la clase objeto» o bien «como este píxel está por debajo del umbral especificado, le voy a asignar la clase fondo».

De este modo, se crea una nueva imagen en la cual se almacenarán estas etiquetas de clase antes obtenidas. Esta nueva imagen tendrá un 255 en todas aquellas posiciones que el algoritmo haya considerado como parte del objeto de interés y tendrá un 0 en aquellas posiciones donde considere lo contrario.

Para que lo entiendas de un modo más gráfico. Imagínate que una imagen viene representada por la siguiente matriz donde cada número se corresponde con el nivel de gris para esa posición.

24891324834
72291847922
12742539142

Suponte que escogemos un umbral de 90. En ese caso, la imagen binaria resultante vendría representada por la siguiente matriz.

0025500
0025500
0000255

Para ver ejemplos prácticos de la umbralización, puedes mirar alguno de nuestros tutoriales de umbralización de imágenes en OpenCV o de umbralización de imágenes en SimpleITK.

Segmentación basada en algoritmos de crecimiento de regiones

Los algoritmos basados en crecimiento de regiones se fundamental en una idea conceptual muy sencilla y fácil de entender. Todo comienza en un punto, que se puede fijar manualmente dentro de la imagen dentro de la zona de interés y, siguiendo un criterio de similaridad, esta semilla se va expandiendo hasta llegar, idealmente, a cubrir toda la extensión de los objetos que nos interesan.

Ese criterio de similaridad se puede basar, por ejemplo, en una diferencia de niveles de gris. Imagínate que la semilla cae en un píxel cuyo valor es 120. Suponte que nuestro criterio de similaridad es «escoge un píxel vecino para expandirte solo si la diferencia es menor a 20».

Este píxel está rodeado por nueve píxeles vecinos cuyos valores son 23, 72, 134, 56, 79, 44, 110, 102 y 109. ¿Qué píxeles escogerá la semilla para expandirse? Los que valen 134, 110, 102 y 109. Una vez se expande la semilla, se expandirán cada uno de los píxeles obtenidos en el paso anterior y así sucesivamente. El proceso finalizará cuando no se pueda expandir ningún píxel más.

Segmentación utilizando modelos deformables

Este método se basa en una curva que se puede deformar para intentar que se ajuste al contorno del objeto a segmentar. El movimiento de estas curvas se puede controlar por medio de una serie de fórmulas, con las que se obtiene la «energía» de esa curva. Básicamente, existen dos tipos de energías: la interna y la externa. La interna permite especificar qué flexibilidad se le quiere dar a la curva. La externa permite decirle al modelo deformable donde está el objeto de interés.

Para ajustarse al contorno de los objetos de interés, la energía total (que será la suma de la interna y la externa) se intenta minimizar. Dicha energía se utiliza como una función de coste para llevar a cabo la segmentación como un problema de optimización. Para realizar la optimización, se pueden utilizar diversos algoritmos de optimización como el gradiente descendente o los algoritmos genéticos, entre muchos otros ejemplos.

Tendencias actuales en la segmentación de imágenes

Si bien estas estrategias continúan utilizándose en gran medida en la actualidad, el auge de las técnicas de aprendizaje profundo ha irrumpido con gran fuerza en el mundo de la segmentación. El procedimiento fundamental de la segmentación con Deep Learning es mucho más intuitivo que los procedimientos anteriores. En este caso, entrenamos a un modelo profundo para que sea capaz de localizar los objetos de interés, pasándole directamente toda la imagen original (incluso puede estar en color).

Dentro del dominio de la segmentación de imágenes con Deep Learning, las arquitecturas de redes convolucionales como las UNet, las SegNet o los autoencoders han demostrado su potencial en estos problemas y, por ello, hoy en día constituyen la tendencia a seguir en muchos ámbitos.

Publicado el Deja un comentario

¿Cómo aplicar un filtro de suavizado con OpenCV en Python?

Una de las partes más importantes a la hora de trabajar con una imagen, para posteriormente aplicar algoritmos de visión artificial es el preprocesamiento. Las imágenes del mundo real poseen ruido, bien sea por los dispositivos de captura, por la digitalización o transmisión de los datos. Para la eliminación o atenuación de este ruido, se utilizan diversas estrategias de preprocesamiento.

Una de ellas es la de suavizar la imagen, para eliminar la aparición de ciertos valores aleatorios que puedan representar ese ruido antes mencionado. Para el suavizado de una imagen, se aplica un filtro conocido como «filtro de paso bajo», es decir, que deja pasar las frecuencias bajas y elimina las frecuencias altas.

¿Qué significa esto? Las frecuencias altas representan bordes, ya que son zonas de la imagen que representan transiciones. Por su parte, todo lo que no sea una transición, es decir, una zona que tiende a un color bastante homógeneo, no será borde y, por tanto, se corresponderá con las frecuencias bajas de la imagen. Sabiendo esto, es fácil deducir que un filtro de paso bajo eliminará los bordes y, de esta forma, difuminará la imagen.

¿Cómo se suaviza una imagen?

Para el suavizado de una imagen, se puede seguir el procedimiento de convertir la imagen al dominio de la frecuencia por medio de la Transformada de Fourier, aplicar un filtro de paso bajo que solo acepte frecuencias debajo de un determinado umbral y, más tarde, volver a convertir esa señal ya procesada al dominio espacial (el dominio original de la imagen), nuevamente.

El método más seguido en la actualidad consiste en utilizar filtros convolucionales para tal fin, que ofrecen la ventaja de que el procesamiento se realiza directamente sobre el dominio no transformado de la imagen (el dominio espacial), evitando la aplicación de la Transformada de Fourier y la aplicación posterior de la Transformada Inversa de Fourier para regresar al dominio espacial.

Los filtros de suavizado se basan en ese proceso de filtrado convolucional utilizando unos kernels con unas características específicas. Generalmente, estos kernels realizan algún tipo de promediado, que puede ser ponderado o no. Pero vamos poco a poco.

Filtro de medias

En el filtro de medias, todos los coeficientes del kernel convolucional tienen valores positivos. De esta forma, conseguimos una integración de los valores de una determinada vecindad. Por ejemplo, supongamos que tenemos un kernel 3 x 3 con todos sus coeficientes a 1, como el que se puede ver en la imagen de abajo.

Con un kernel como el que aquí se describe, no solo se tomaría el valor central (indicado con color rojo) si no también esa vecindad local de 3 x 3 que el propio kernel indica. Por tanto, el resultado final (es decir, el valor que se le asignará al píxel que se está procesando), será la suma de los nueve valores de la vecindad (de ahí el concepto de la integración de los valores).

Además, para garantizar que el valor de salida del filtro esté dentro del rango de niveles de gris de la imagen original (generalmente en el rango [0, 255]), se debe realizar un promedio (de ahí que, además de aplicar el kernel, se divida el resultado entre 9, para este caso).

Filtro de medias en OpenCV

Realizar un filtro de medias en OpenCV es un procedimiento muy sencillo. Como puedes ver a continuación, se puede limitar a cuatro líneas.

En primer lugar, se realiza la importación de la librería. En segundo lugar, se lee la imagen con la función «cv2.imread()». Sobre esta imagen, ahora se podrá realizar un suavizado con un filtro de medias, haciendo uso de la función «cv2.blur()».

Esta función recibe dos parámetros: la imagen de entrada que se desea suavizar y el tamaño del kernel, de 10 x 10 para este ejemplo. Ya que se trata de simple filtro de medias en este caso, todos los coeficientes del kernel valdrán 1. Una vez aplicado, se almacena en un fichero de imagen o se muestra por pantalla con «cv2.imshow()». En este caso, hemos decidido almacenar todo en un fichero PNG con la función «cv2.imwrite()».

El resultado que se obtiene es algo como lo que se puede ver a continuación.

Para ajustar el nivel de suavizado, se debe variar el valor del tamaño del kernel. Este sería un ejemplo con un kernel de tamaño mayor, en este caso, de 20 x 20.

Como se puede observar, al aplicar un filtro de medias con un tamño de kernel mayor (20 x 20, en este caso), el difuminado de la imagen es mucho más notable.

Filtro gaussiano

El filtro gaussiano es un caso particular del filtro de medias. Realmente, consiste en realizar un filtro de medias ponderado. ¿Qué quiere decir esto? Para entenderlo, hay que tener en cuenta que, en el filtro de medias normal, todos los píxeles de la vecindad tienen el mismo peso. Pero, razonadamente, sabemos que no todos los píxeles deberían tener el mismo peso, ya que los píxeles más lejanos dentro de la vecindad influyen menos sobre el píxel central que los más cercanos.

Una alternativa para atender a estas ideas es utilizar un kernel cuyos coeficientes sean los valores de una función gaussiana. Esta función gaussiana calculará un valor en función de la posición en la que el coeficiente se encuentre dentro del kernel. De forma natural, estaremos ejecutando un suavizado con un filtro de medias ponderado.

Filtro gaussiano en OpenCV

Realizar un filtrado gaussiano en OpenCV también es un procedimiento muy sencillo. Igual que en el caso anterior, se importa la librería correspondiente, se lee la imagen, se aplica la función correspondiente y se almacena en un fichero y se visualiza.

En este caso, se hace uso de la función «cv2.GaussianBlur()» que recibe como parámetros la imagen sobre la que se desea aplicar el suavizado, el tamaño del kernel y el valor de sigma de la función gaussiana. Generalmente, se suele dejar el valor a 0 ya que, de este forma, la propia función obtiene un valor de sigma automáticamente a partir del tamaño del kernel.

Después de aplicar el filtro correspondiente, el resultado obtenido se puede observar a continuación.

Es posible que no se aprecie demasiado las diferencias entre ambas imágenes porque el tamño del kernel del suavizado es demasiado pequeño. Del mismo modo que ocurre con el filtro de medias, para obtener un difuminado mayor es preciso aumentar el tamaño del kernel. Más abajo, se puede observar el mismo ejemplo pero utilizando, en este caso, un filtro gaussiano de tamaño 51 x 51.

En este caso, con un tamaño de kernel mucho mayor (51 x 51) el difuminado obtenido es considerablemente más notorio.

Es importante tener en cuenta que, debido a cuestiones internas de la función utilizada, los kernels deben tener un tamaño impar. Por ello, no se podrá realizar un suavizado gaussiano con un kernel 4 x 4 o con un kernel de 50 x 50. En caso contrario, la propia función devolverá un error similar a este:

cv2.error: OpenCV(4.4.0) /tmp/pip-req-build-99ib2vsi/opencv/modules/imgproc/src/smooth.dispatch.cpp:296: error: (-215:Assertion failed) ksize.width > 0 && ksize.width % 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1 in function ‘createGaussianKernels’

Filtro de medianas

Es ampliamente conocido en el mundo de las matemáticas que la media es un estadístico muy influenciado por los valores atípicos que pueden aparecer en una muestra. Es decir, supongamos que tenemos un conjunto de valores del estilo.

[1.70, 1.90, 2.10, 3.50, 30.90, 2.90, 1.70]

Claramente, se observa que hay un valor que desentona dentro de esa distribución, el 30.9, por lo que representa un valor atípico dentro del conjunto de datos especificado. La media de estos valores será aproximadamente 6.39. Evidentemente, este valor no es representativo del conjunto de datos, ya que los datos «normales» (todos los que no son atípicos, en este caso) no se aproximan a ese supuesto valor medio.

Si eliminásemos ese valor atípico, la media sería de 2.30, lo cual ya parece más coherente con el conjunto de datos. Este concepto, conocido como la media recortada, es perfectamente aplicable al ámbito del suavizado de imágenes. Un concepto similar es el de la mediana, que colocaría los valores anteriores en orden…

[1.70, 1.70, 1.90, 2.10, 2.90, 3.50, 30.90]

Y, en este caso, como el tamaño de la lista es impar, asumiríamos el valor central (que deja mismo número de valores a derecha e izquierda) como la mediana. Por tanto, para este caso, sería el 2.10 lo cual, nuevamente, es un valor más coherente. En resumen, si fuera de interés, utilizar un suavizado que sea robusto a valores atípicos, los filtros de medianas son la alternativa que se suele utilizar.

Filtro de medianas en OpenCV

Por último, el filtro de medianas también es muy sencillo de aplicar en OpenCV. Para ello, se aplica el mismo procedimiento que en los casos anteriores, haciendo uso de la función «cv2.medianBlur()».

Esta función recibe dos parámetros. En primer lugar, la imagen sobre la que se quiere realizar el suavizado. En segundo lugar, se debe especificar el tamaño del kernel para el filtro. En este caso, el tamaño del kernel también debe estar especificado por un valor positivo impar por cuestiones internas de la función.

Una vez que se aplican los procesos correspondientes, se obtiene imágenes con resultados como los que se pueden observar a continuación. Una vez más, cuanto mayor sea el tamaño del kernel mayor será el nivel de difuminado del filtro de medianas.

Imagen original.
Imagen después de un filtrado de medianas de tamaño 51.
Imagen después de un filtrado de medianas de tamaño 11.
Imagen después de un filtrado de medianas de tamaño 5.
Publicado el Deja un comentario

¿Cómo umbralizar una imagen con OpenCV en Python?

La umbralización en OpenCV utilizando Python es una tarea que se puede llevar a cabo de una forma muy sencilla. La librería de OpenCV nos ofrece una serie de opciones para realizar esta binarización, que mostraremos una por una a continuación.

Binarización simple

Debemos recordar que la binarización simple consiste en umbralizar los valores de gris utilizando, para ello, un valor seleccionado manualmente, lo cual da lugar a una imagen binaria.

En las imágenes binarias, se suele utilizar el valor de gris más intenso (es decir, más próximo a blanco) para colorear las zonas que se corresponden con los objetos de interés. Por su parte, el valor de gris más oscuro (más próximo al negro) se utilizará para colorear el fondo, es decir, todo aquello que no sea el objeto de interés. De hecho, lo más común es utilizar el blanco (valor de 255) para las zonas de interés y el negro (valor de 0) para el fondo.

Dicho esto, pasemos al ejemplo que nos interesa. Supongamos que se desea segmentar todos los objetos que se pueden ver en la siguiente imagen.

Ejemplo de imagen para su umbralización con OpenCV

Parece bastante aceptable que una umbralización podría ser suficiente para poder segmentar esos objetos de interés con una enorme precisión. Para ello, se puede utilizar el código que se muestra a continuación.

Estos son los pasos a seguir a la hora de realizar una umbralización simple sobre una imagen RGB, junto a su código correspondiente, explicándolo de una forma más detallada.

1. Importar librerías y leer la imagen de entrada

Se importan todas las librerías necesarias para el proceso. Para este caso, las librerías que se utilizan son OpenCV para el trabajo con las imágenes, Numpy para ciertas tareas matemáticas y Matplotlib para la graficación del histograma. A continuación, con el método «imread» de la librería de OpenCV, se leerá la imagen de entrada a una matriz de tres dimensiones (ancho, alto y canal de color RGB).

2. Obtención del histograma (opcional)

Opcionalmente, se puede graficar el histograma de la imagen para obtener alguna conclusión por medio de la exploración visual.

Para este ejemplo, se puede obtener un histograma como el de arriba. En este caso, se decide obtener el histograma del canal verde, pero se podría obtener para cualquiera de los otros dos canales.

3. Obtener una imagen de un solo canal para la umbralización

Antes de umbralizar la imagen, dado que es RGB, se debe tomar una decisión. Es necesario tener una entrada de un solo canal, para lo cual existen principalmente dos opciones.

La primera consiste en convertir la imagen en color a escala de grises.

La segunda consiste en quedarse con un solo canal (R, G ó B, es decir, el canal rojo, el verde o el azul) de la imagen original.

Existe también una tercera opción, muy similar a la de asumir un único canal de la imagen RGB pero, en este caso, utilizando otro modelo de color diferente como HSL o HSV, por ejemplo.

Para este caso, se ha decidido coger únicamente el canal «1» que, dado que en OpenCV las imágenes se representan con un modelo BGR (en lugar de RGB), se corresponde con el canal verde (canal G).

4. Llevar a cabo la umbralización

Sobre el canal seleccionado, se considera un valor umbral concreto que se especifica manualmente. Con frecuencia, esta selección se hará a base de prueba y error, pero la visualización del histograma puede aportar información a priori de cuál puede ser el valor idóneo.

La función «cv2.threshold» utiliza cuatro parámetros de entrada:

  • La imagen que se desea umbralizar (de un solo canal).
  • El valor umbral.
  • El valor de nivel de gris que queremos ponerle a los píxeles de la clase «1», es decir, a los que superen el valor umbral antes especificado. Generalmente, este valor debería ser 255.
  • El tipo de umbralización que se desea llevar a cabo. Existen varias opciones.

OPCIONES DE LA FUNCIÓN «CV2.THRESHOLD» PARA UMBRALIZAR

cv2.THRESH_BINARY: umbralización estándar. Todos aquellos píxeles que superen el valor umbral será considerado como píxeles de objeto (y, para el ejemplo que estamos tratando, estos píxeles tendrán un valor de 255) y todo lo demás se corresponderá con el fondo (tendrá un valor de 0).

Teniendo ImRes(x, y) como la imagen resultante de la umbralización, Im(x, y) como la imagen que se desea umbralizar, OBJVAL como el valor de los píxeles que superan el umbral y T como el valor umbral, se tiene la siguiente expresión:

    \[ ImRes(x, y)= \left\{ \begin{array}{lcc}              OBJVAL &   si  & Im(x, y) > T \\              \\ 0 &  si & Im(x, y) \leq T  \\              \end{array}    \right. \]


cv2.THRESH_BINARY_INV: el procedimiento se ejecuta de la misma forma que en el caso anterior pero, en este caso, a la inversa. De este modo, todo lo que sobrepase el valor umbral tendrá un valor de 0 y, lo que se quede por debajo de dicho umbral, recibirá un valor de 255.

Teniendo ImRes(x, y) como la imagen resultante de la umbralización, Im(x, y) como la imagen que se desea umbralizar, OBJVAL como el valor de los píxeles que superan el umbral y T como el valor umbral, se tiene la siguiente expresión:

    \[ ImRes(x, y)= \left\{ \begin{array}{lcc}              OBJVAL &   si  & Im(x, y) < T \\              \\ 0 & si & Im(x, y) \geq T  \\              \end{array}    \right. \]


cv2.THRESH_TRUNC: en este caso, los píxeles que no sobrepasen el umbral conservarán su valor en la imagen resultante y, aquellos que sí lo superen, aparecerán en la imagen resultante con el valor umbral. En otras palabras, esta funcionalidad hace que ningún píxel de la imagen sobrepase el valor umbral en la imagen resultante. Bajo este punto de vista, no se está realizando propiamente una binarización, ya que la imagen resultante seguirá estando en escala de grises.

Teniendo ImRes(x, y) como la imagen resultante de la umbralización, Im(x, y) como la imagen que se desea umbralizar, OBJVAL como el valor de los píxeles que superan el umbral y T como el valor umbral, se tiene la siguiente expresión:

    \[ ImRes(x, y)= \left\{ \begin{array}{lcc}              T &   si  & Im(x, y) > T \\              \\ Im(x, y) & si & Im(x, y) \leq T  \\              \end{array}    \right. \]


cv2.THRESH_TOZERO: en este caso, tampoco se obtiene una imagen binaria. Todo lo que supere el valor umbral, conservará es valor en la imagen resultante, mientras que los píxeles que no lo superen se pondrán a cero.

Teniendo ImRes(x, y) como la imagen resultante de la umbralización, Im(x, y) como la imagen que se desea umbralizar, OBJVAL como el valor de los píxeles que superan el umbral y T como el valor umbral, se tiene la siguiente expresión:

    \[ ImRes(x, y)= \left\{ \begin{array}{lcc}              Im(x, y) &   si  & Im(x, y) > T \\              \\ 0 &  si & Im(x, y) \leq T  \\              \end{array}    \right. \]


cv2.THRESH_TOZERO_INV: esta umbralización funciona de la misma forma que el caso anterior, pero a la inversa. Todo aquello que supere el valor umbral se pondrá a cero y, los píxeles restantes, conservarán su valor en la imagen resultante.

Teniendo ImRes(x, y) como la imagen resultante de la umbralización, Im(x, y) como la imagen que se desea umbralizar, OBJVAL como el valor de los píxeles que superan el umbral y T como el valor umbral, se tiene la siguiente expresión:

    \[ ImRes(x, y)= \left\{ \begin{array}{lcc}              0 &   si  & Im(x, y) > T \\              \\ Im(x, y) &  si & Im(x, y) \leq T  \\              \end{array}    \right. \]


Cabe destacar que esta imagen devuelve una dupla donde el primer elemento es el valor umbral con el que se ha realizado la umbralización, que será el mismo que has puesto como parámetro, en este caso (aunque no tenga mucho sentido, más adelante verás que, con la umbralización de Otsu, es importante que la función lo devuelva). El segundo elemento de esa dupla será la propia imagen ya umbralizada.

5. Visualización de la imagen resultante

Una vez escogido el valor umbral y después de haber aplicado la umbralización correspondiente, la imagen binaria resultante se almacena en un fichero de imagen con el formato que deseemos, comúnmente «.jpeg», «.jpg» o «.png».

Por supuesto, también tendrías la opción de mostrarlo en una ventana interactiva con la función que se muestra más abajo.

6. Discutir los resultados del método

El resultado que se obtiene para el ejemplo se puede observar a continuación. Para este caso, se ha considerado una umbralización simple invertida (flag «cv2.BINARY_THRESH_INV») ya que, asumiendo el canal verde, se observa que los niveles de gris de los objetos se encuentran en los valores bajos y, los píxeles de fondo, tienen una gran luminosidad.

Por lo general, se observa que un valor umbral de 220 sobre el canal verde de esta imagen, es suficiente para hacer una segmentación bastante precisa. Un objeto para el que la segmentación no es del todo precisa se puede observar en la imagen de a continuación, marcada en rojo.

Binarización con el algoritmo de Otsu

En este caso, en lugar de escoger de forma manual el valor umbral, se utiliza el método de Otsu, el cual es capaz de obtener dicho valor de forma automática. De este modo, el procedimiento a seguir es muy similar al de la binarización simple. De hecho, puede utilizarse exactamente la misma función «cv2.threshold», solo habrá que incluir el flag «cv2.THRESH_OTSU» a mayores del de «cv2.BINARY_THRESH_INV», como se indica en el código de a continuación.

Como se indicaba antes, el hecho de que la función de umbralización devuelva el umbral, cobra sentido. Ya que es el método quien selecciona el valor concreto, es útil conocerlo a posteriori. Esto se puede hacer sencillamente con un «print(ret)», ya que es un simple escalar.

Particularmente, para este ejemplo, el método de Otsu parece funcionar peor, ya que segmenta menos píxeles de algunos objetos. Se ha utilizado de nuevo el canal verde pero, en este caso, el umbral seleccionado por el método ha sido 149.

Hasta aquí el post de hoy. Si tienes alguna duda o sugerencia, no dudes en dejar tus comentarios. ¡Hasta la próxima entrada!

Publicado el Deja un comentario

¿Cómo binarizar una imagen en Simple ITK con Python?

¿En qué consiste binarizar una imagen?

La binarización de las imágenes consiste en buscar un valor umbral de nivel de gris para distinguir entre aquello que no sea relevante en la imagen y aquello que sí lo sea. Por ejemplo, en la siguiente imagen tenemos una hoja sobre un fondo blanco y deseamos quedarnos únicamente con los píxeles que se corresponden con la hoja. Para ello, podemos hacer una sencilla binarización.

¿Por qué se llama binarización? Sencillamente, porque convierte la imagen de salida en una imagen binaria, es decir, con únicamente dos niveles de gris. Esto no tiene porque ser exclusivamente así, ya que se podría buscar, por ejemplo, detectar dos objetos considerablemente diferentes en la imagen y distinguirlos del fondo. En ese caso, podría ser necesario utilizar varios umbrales. Es por ello que, en general, a este tipo de procedimiento se le suele llamar umbralización.

Este es un caso exitoso de umbralización de una imagen para segmentar el objeto. Sin embargo, no te creas que esto ocurre siempre así. Por lo general, los problemas de segmentación no son para nada sencillos, ya que no hay ningún método que funcione para todas las imágenes. Un ejemplo de segmentación con resultados no tan buenos, se puede ver con la imagen de la hoja que tienes a continuación.

Y, para este método, la binarización está funcionando bastante bien. Es cierto que estas imágenes están muy bien hechas… y es por ello que no son representativas de lo que suele ocurrir en la realidad, donde la calidad suele ser más pobre y resolver una segmentación resulta mucho más complejo.

A nivel de histograma, el procedimiento que se está aplicando es muy sencillo de entender. Simplemente, a los valores que caen a la derecha del umbral les damos un valor y, a los que caen al otro lado, les damos otro valor diferente.

Ejemplo de umbralización de una imagen RGB en el canal azul. Como valor umbral, se utiliza el 35.

Como puedes observar, la selección del umbral es completamente manual, ya que estamos en el caso de binarización más simple. Este umbral debe obtenerse a base de prueba y error.

Pero no es la única forma de obtener una imagen binaria. Existen otros procedimientos que permiten obtener el umbral de forma automática, como es el caso del algoritmo de Otsu. Por lo general, todos estos métodos van a estar implementados en cualquier librería de imagen que utilices.

¿Cómo realizar la umbralización de una imgen en la práctica?

En este caso, vamos a utilizar la librería Simple ITK para llevar a cabo diversos procedimientos de binarización de las imágenes.

Binarización simple con Simple ITK en Python

En este caso, utilizaremos el método de binarización simple para umbralizar la imagen. Por tanto, debemos especificar explícitamente los valores de umbral deseados. En este caso, se toma una imagen en color RGB de la cual solo se coge el canal azul (que en OpenCV es BGR, con lo que se coge el primer canal, es decir, el «0»).

Este sería el resultado con el código propuesto arriba.

Binarización con el algoritmo de Otsu en SimpleITK

Con el algoritmo de Otsu, no es necesario selccionar de forma manual el valor de umbral deseado. El procedimiento a seguir en la implementación es muy similar, ya que sencillamente se debe cambiar la función de binarización simple con la correspondiente al algoritmo de Otsu.

Al ejecutar este código, se obtiene una salida con una apariencia como la que se muestra a continuación.

Además, el código «print(otsu_filter.GetThreshold())» permite obtener el valor de umbral que ha encontrado el algoritmo. En este caso, nos ha devuelto «134».

Publicado el Deja un comentario

¿Cuál es la diferencia entre el aprendizaje supervisado y no supervisado en machine learning?

🔥🔥 En este post, vamos a hablarte de un TEMA muy TOP, que está dando mucho de qué hablar en los últimos años. Estamos seguros de que has escuchado miles de veces el término «Inteligencia Artificial» y otros términos como «Big Data» o «Aprendizaje Automático». Bien, para que te puedas adentrar en el contexto de lo que todo esto significa debemos referirnos a un término clave: datos. Vivimos en la era de los datos, ya que tenemos una enorme cantidad de dispositivos que están emitiendo información todo el día: ordenadores, móviles, dispositivos inteligentes… por medio de Internet, gracias a las vías de comunicación principales: redes sociales, plataformas de almacenamiento en la nube…

Introducción al Aprendizaje Automático

Como te puedes imaginar, si una empresa quiere hacer el estudio de mercado del comportamiento de los usuarios a la hora de comprar X producto, no se van a poner a analizar todos los datos de forma manual… porque les llevaría siglos, básicamente.

Para lidiar contra estos problemas, en una era donde la dificultad no está en generar ni obtener datos (porque de eso ya tenemos de sobra), las técnicas de inteligencia artificial han supuesto un cambio en la forma de hacer las cosas. Dentro de este área genérica de la inteligencia artificial, existen varias ramas, de las cuales el aprendizaje máquina o aprendizaje automático es una de las más conocidas.

En una definición muy burda, la Inteligencia Artificial es un conjunto de estrategias que se utiliza cuando algo no se puede resolver con un algoritmo convencional o no se puede hacer en un tiempo razonable. Y dirás… ¡Uff! Ya empezamos con conceptos complicados. Mejor veámoslo con un ejemplo.

El típico ejemplo que se suele dar como primera pincelada del aprendizaje máquina dice así: imagínate que tienes un conjunto de imágenes y quieres determinar si en ellas aparece una cara o no. Para una persona, es una tarea relativamente sencilla pero, a priori, para una máquina no. Pues bien… el aprendizaje máquina nos permite lidiar contra este tipo de cosas. El cómo lo conseguimos es un proceso un poco más complicado de explicar. Pero vamos poco a poco.

Tipos de aprendizaje máquina

Existen tres tipos principales de aprendizaje máquina:

  • Aprendizaje supervisado.
  • Aprendizaje no supervisado.

Cada tipo de aprendizaje tiene unas particularidades y está dirigido a unas ciertas aplicaciones, como veremos a continuación.

Aprendizaje supervisado

El aprendizaje supervisado es un tipo de aprendizaje automático que se caracteriza por la necesidad de datos etiquetados manualmente para que pueda funcionar. ¿Y qué es esto de los datos etiquetados manualmente? Retomando el ejemplo de antes, las imágenes de nuestro conjunto de entrada van a ser etiquetados como «imagen con cara», «imagen sin cara». La cuestión es que antes de que nuestro sistema de aprendizaje sea capaz de recibir una imagen y decir si tiene una cara o no, primero necesita que nosotros le enseñemos qué es una cara.

Para hacer el etiquetado manual en este caso, es preciso coger una a una todas las imágenes y almacenar en algún sitio algo así como «esta imagen tiene una cara, esta no, esta tampoco, esta sí, esta no, esta sí, esta no…». A un nivel matemático y más cercano a la informática, la presencia de una cara en una imagen podría ser un «1» y la ausencia sería representada por un «0».

¿Y cómo conseguimos con esto que nuestro sistema de aprendizaje sea capaz de resolver la tarea de forma automática? Para ello, es necesario lo que se denomina como proceso de entrenamiento. Este proceso consiste, a grandes rasgos, en enseñarle a nuestro sistema (lo que en muchas ocasiones llamamos modelo de aprendizaje y, por simplificar, modelo) que «a esta imagen que tiene una cara se le asigna la etiqueta 1 y, a esta imagen que no tiene ninguna cara, se le asigna la etiqueta 0».

Eso se hace con todas las imágenes que tenemos en nuestro conjunto (lo que comúnmente se llama conjunto de datos) en repetidas ocasiones, hasta que nuestro modelo haya aprendido a saber qué es una imagen de una cara y qué no lo es. De esta forma, cuando nosotros le pasemos una imagen nueva que no haya visto previamente, el modelo debería ser capaz de identificar correctamente si en esa imagen hay una cara o no. Deberías estar ahora mismo lleno de dudas y preguntándote cómo se consigue todo esto. Lo cierto es que depende de muchas cosas y no es conveniente explicarlo en este apartado, ¡ya que solo hablar de esto llevaría varios posts!

En este mundo del aprendizaje supervisado, existen principalmente dos tipos de problemas.

PROBLEMAS DE CLASIFICACIÓN

Los primeros tipos de problemas de los que vamos a hablar son los de clasificación. Para ellos, la salida de nuestro modelo será binaria y nos dirá si la imagen pertenece a una clase o no. En el ejemplo mencionado hasta ahora, el modelo debería determinar si una imagen dada pertenece a la clase «imagen de caras» o, por el contrario, no pertenece a dicha clase. En problemas de clasificación destacan algoritmos como las redes de neuronas, las máquinas de soporte vectorial o el algoritmo kNN.

PROBLEMAS DE REGRESIÓN

El segundo tipo de problemas es el de regresión. En este caso, lo que se pretende hacer no es obtener un modelo que nos devuelva un valor binario, si no un número que represente una variable determinada. Por ejemplo, determinar el valor que debería tener una casa en función de sus características.

Imáginate que disponemos de un conjunto de datos con muchos registros de diferentes casas. Para cada registro, se especifican cosas como tamaño, número de plantas, si tiene jardín o no, en qué barrio se encuentra, el número de dueños que ha tenido… y todo el conjunto de cosas que nos podamos imaginar que influyan en el valor de una casa. Junto a esas características, se debe especificar el precio concreto de esa casa. Ese precio es equivalente a la etiqueta de los problemas de aprendizaje supervisado, en el sentido de que primero debemos proporcionarlo de forma manual.

Una vez hecho esto, el modelo de regresión se entrena con el conjunto de registros de casas varias veces hasta que aprenda a predecir bien los precios. Si ha sido convenientemente entrenado, al pasarle las características de una nueva casa que no ha visto previamente debería ser capaz de predecir de manera correcta su precio.

Algoritmos no supervisados

Existe otra variante del aprendizaje automático que se denomina como «aprendizaje no supervisado». En este caso, nosotros no tenemos que proporcionarle al modelo muestras etiquetadas manualmente, como ocurría antes. Eso sí, no servirá para resolver la misma clase de problemas. Estos algoritmos no supervisado suelen utilizarse para resolver lo que se denomina clustering o agrupamiento. Para este caso, nosotros tenemos un conjunto de cosas que queremos repartir en grupos en caso de que presenten similaridades entre sí.

Por ejemplo, imagínate que tienes un conjunto de personas las cuales quieres organizar en diferentes grupos por la razón que sea. Suponte que quieres crear cuatro grupos: mujeres altas, mujeres bajas, hombres altos y hombres bajos. Para caracterizar a esas personas, debes representarlas en función de su sexo y altura.

Pues bien, el modelo de aprendizaje no supervisado tomará esos datos y establecerá por sí mismo un criterio para discernir, primero entre hombres y mujeres y, más tarde, entre personas altas y bajas, ya que las va a agrupar en función de su estatura, estableciendo automáticamente un umbral. Si se supera ese umbral, se considera del grupo «alto» y, si no se supera, quedaría en el grupo «bajo». Lo cierto es que esto es un ejemplo muy simple… estos métodos no son tan inmediatos de usar, pero como ejemplo introductorio no está mal.

Para este tipo de modelos de aprendizaje, también es necesario un cierto proceso de entrenamiento pero, en ningún caso, requerirá de muestras etiquetadas de forma manual. Uno de los algoritmos más conocidos de aprendizaje no supervisado es el k-medias o cualquiera de sus variantes.

Publicado el Deja un comentario

Las claves sobre Arduino

🤙🤙Bienvenido al magnífico post donde te mostraremos todas las claves de Arduino, tanto en el caso de que seas un principiante que no tenga apenas idea de qué va esto como si eres un profesional curtido en mil batallas. En este post, vamos a hablar sobre qué es Arduino, por qué te podría resultar interesante aprenderlo, en qué dominios se puede aplicar y, de regalo, te recomendamos las principales placas Arduino además de todo el software y los componentes electrónicos indispensables para que puedas construir tus circuitos digitales programables.

✔ No solo eso, si no que también te damos las claves sobre las principales expansiones que existen para las placas, versiones más avanzadas del hardware de Arduino y algunos libros para que te puedas iniciar en la materia o para que tengas algunas ideas de circuitos que podrías diseñar. Dicho esto, ¡comencemos con todas las claves sobre la plataforma Arduino!

Resumen sobre las características de Arduino

UtilidadDiseño e implementación de circuitos electrónicos programables. Orientado al Internet de las cosas (IoT) para dominios como la domótica.
DificultadMedia. Las placas Arduino son sencillas de programar, pero se requiere de un conocimiento en electrónica.
CaracterísticasEs una plataforma libre de hardware y software para el desarrollo de proyectos donde se necesitan dispositivos embebidos.

Comprar los componentes importantes para trabajar con Arduino

Lo fundamental para trabajar con Arduino es disponer de una placa y descargar un entorno de programación compatible, como el que puedes ver en la página oficial. En caso de que quieras ponerte a trabajar por tu cuenta o crees que necesitarás una placa para un curso que vas a hacer, aquí te recomendamos las principales cosas que te podrías comprar para cubrir esas necesidades.

Placas de Arduino individuales

La primera opción a la hora de elegir una placa Arduino es comprar alguno de los modelos originales. Sin embargo, ya que Arduino es una plataforma libre y gratuita, algunos fabricantes han decidido replicarla y vender sus propias versiones de este hardware. Este es el caso de la marca Elegoo, cuyos modelos de placas son totalmente compatibles con el entorno de programación oficial de Arduino. Siempre es preferible comprar la versión del fabricante original pero, del mismo modo, Elegoo ofrece muchos kits que incorporan no solo la placa, si no también muchos componentes electrónicos para poder diseñar tus circuitos.

Para aquellos que están comenzando, los kits de Elegoo son, sin duda, una magnífica opción. Cuando conozcas un poco más a fondo la plataforma y los componentes que te hacen falta, seguramente te resulte más interesante comprar la placa original de Arduino y buscar otra forma de comprar los elementos electrónicos que necesitas para tus proyectos.

Placa arduino uno

La placa Arduino UNO es la más básica y la que mucha gente utiliza como iniciación. Esta placa tiene 14 pines digitales y 6 pines analógicos que se pueden programar por medio de código utilizando el entorno de programación de Arduino IDE (el oficial). Elegoo se ha encargado de clonar su arquitectura, así que esta marca también se ofrece como kit de iniciación para aquellos que quieran comenzar en el mundo de la electrónica.

Los kits de iniciación suelen venir con cosas muy interesantes y útiles para el aprendizaje como es el caso de LEDs, resistencias, placa de prototipos, cables específicamente diseñados para trabajar con pines y placas de prototipos, condensadores, LEDs de 7 segmentos, pantallas LCD, sensores de luz y temperatura, sensores de ultrasonidos, motores y servomotores, potenciómetros, pulsadores o relés.

  • Placa individual Arduino UNO.
  • 14 pines digitales y 6 pines analógicos.
  • Placa individual Elegoo.
  • Kit de iniciación de Elegoo.
  • Inckuye la placa y algunos componentes electrónicos de utilidad.

Placa Arduino Mega

En caso de que la placa Arduino UNO no te llegue porque no tiene el suficiente número de pines para las aplicaciones a las cuales lo estás destinando, existen otros modelos más complejos y con más funcionalidades como es el caso de la placa Arduino MEGA, que destaca por ser de mayor tamaño, poseer un mayor número de pines y tener un microprocesador de mayor potencia. Posee un total de 54 pines digitales y 16 pines analógicos que, del mismo modo que en la Arduino UNO, se pueden programar como uno considere oportuno. De esta placa existe incluso una versión mejorada denominada Arduino MEGA 2560.

  • Arduino MEGA 2560.
  • Elegoo MEGA 2560.
  • Kit de iniciación Elegoo MEGA 2560.

Otras placas de Arduino

Existen algunos otros modelos como la placa Arduino Leonardo, Arduino 101, Arduino Esplora o la Arduino Genuino Zero. Cada uno de estos modelos son como una evolución en cierta forma de la Arduino UNO y tienen una serie de características especiales que te podrían interesar o no para tus proyectos. Cada una de ellas, de este modo, tiene algunas cualidades particulares, así que conoce primero lo que necesitas para tu proyecto y estudia cuál es la mejor opción entre todas ellas.

Por otra parte, cabe destacar que también existen algunas placas más sencillas que la Arduino UNO como es el caso de la Arduino NANO. Lo mejor de esta plataforma es que gracias a la modularidad, puedes comprar varias placas que interactuarán entre sí. Por ejemplo, puede resultarte útil tener una placa más avanzada como centro del sistema, la cual a su vez estará conectada con otras placas más sencillas. De esta forma, la placa central tendría el control principal del sistema y cada una de las placas restantes se encargarían de realizar tareas específicas. Este tipo de desarrollo es muy útil, por ejemplo, para un diseño domótico.

  • Arduino NANO.

Accesorios para las placas Arduino y otras cosas útiles

Si por algo destaca Arduino, es por su gran modularidad y la gran capacidad que tiene para añadir extensiones sobre las placas originales. Del mismo modo, también hay fabricantes que se atreven a diseñar sistemas hardware más complejos basados en Arduino, como es el caso de algunos robots. Como lo último que nos gustaría destacarte de Arduino, te hablaremos los libros disponibles para que puedas iniciarte en este mundo y para que cojas ideas cuando no tengas muy claro qué circuitos puedes diseñar y programar con esta plataforma.

Placas Arduino y conexión Wi-Fi, conexión Bluetooth o sistemas de comunicación similares

Para la conexión Wi-Fi, conexión Bluetooth o cualquier otro tipo de sistema de comunicación que no sea el USB que incorpora la placa Arduino de serie, puede ser necesaria una placa de expansión o directamente la compra de una placa que incorpore ese tipo de funcionalidad. La desventaja de comprar una extensión es que te resultará más complicado de montar.

  • Arduino UNO Wi-Fi REV2.
  • Módulo de Bluetooth compatible con Arduino.

Otros dispositivos Arduino

Tambien existen en el mercado piezas de hardware más complejas que tienen una funcionalidad más concreta que las placas Arduino básicas que has visto hasta el momento. Estamos hablando, por ejemplo, de modelos de robots que están integrados con componentes de Arduino y que, por tanto, son incluso compatibles con el entorno de programación de Arduino IDE, con lo que serás capaz de trabajar directamente con un robot utilizando la misma filosofía que con cualquier placa Arduino.

  • Robot Elegoo UNO R3.

Libros para aprender y para coger ideas

Y, por último, por aquí tienes algunos libros con los que podrás iniciarte en el mundo de Arduino además de para saber qué circuitos puedes diseñar cuando te quedes sin ideas.

  • Arduino: 2020 Beginners Guide to Learn Arduino Programming.

¿Qué cosas debo saber antes de conocer a fondo Arduino?

Arduino es algo completamente opuesto en ciertos sentidos en lo que respecta al ordenador convencional. En un ordenador estás acostumbrado a hacer todo tipo de cosas como manejar documentos, navegar en Internet, escuchar música o jugar a videojuegos. En otras palabras, los ordenadores personales están diseñados para cosas muy genéricas. En este sentido, Arduino es algo completamente distinto.

En ciertos entornos, es imprescindible desarrollar elementos que resuelvan tareas muy concretas. Un elemento tan sencillo como un cepillo eléctrico, requiere de un pequeño hardware que controle las diferentes funciones del mismo. Pero evidentemente, no se necesita un ordenador personal para hacer que un cepillo eléctrico funcione.

Aquí entra en juego lo que se denomina sistemas embebidos, embarcados o empotrados. Son sistemas con unas características muy concretas y que están hechos a medida para una cierta aplicación, como por ejemplo puede ser el cajero automático de un banco o una caja autoservicio de una tienda. La idea de usar sistemas muy específicos es que hay que aprovechar los recursos al máximo. Si sabemos que esta máquina solo se va a usar como cajero automático, ¿por qué vas a diseñar un sistema que sería capaz de llevar un hombre a la Luna? No se pueden gastar recursos y tiempo en cosas que no van a valer la pena.

Con esta idea en mente, pasemos a hablar directamente de Arduino y de qué tiene que ver con los sistemas embebidos. Esta plataforma de hardware y software libres nació con fines didácticos, pero es una plena demostración del potencial que puede tener un sistema específico y barato dentro de sistemas de carácter domótico y del famoso «Internet de las cosas» (IoT, «Internet of Things»).

¿Qué son las placas Arduino?

Las placas Arduino tienen un chip llamado microcontroladora, donde integran todo lo importante. Si en un ordenador de sobremesa, la memoria y el procesador van por separado, en el caso de estas placas va todo integrado en el mismo lugar. Pues bien… ese es el cerebro que lo controla todo. Pero llega lo más importante… ¿para qué puede valer eso?

Arduino se caracteriza por ser una placa que por sí sola no tiene ninguna utilidad, ya que su verdadero potencial radica en el montaje de circuitos electrónicos externos con componentes como diodos, LEDs, resistencias, pulsadores, relés, condensadores o motores (entre muchos otros) con la intención de programar algún tipo de comportamiento.

Todo esto se consigue por medio de esa microcontroladora que se mencionaba antes, la cual tiene el poder de control sobre un conjunto de pines. ¿Qué son esos pines? Son un elemento fundamental en una placa Arduino y son de dos tipos: de entrada y de salida. Los pines de entrada son un elemento de hardware de la placa que se pueden alimentar con un voltaje. Más tarde, por medio de programación, se puede leer ese valor y hacer lo que te apetezca… pero vamos poco a poco.

Por su parte, los pines de salida hacen lo contrario. Tienen un nivel de voltaje que se puede escoger con un poco de programación. Además, la propia placa tiene otros pines que hacen cosas fijas y más concretas, de modo que no se pueden programar. Un ejemplo de estos pines son los que dan un valor de tensión concreto todo el tiempo, que suele ser de 5 V, 3.3 V ó de 0 V, este último utilizado como referencia, masa o tierra de los circuitos.

Cabe destacar que los pines pueden ser digitales, en caso de que solo puedan distinguir entre nivel de voltaje bajo y alto o analógicos, en caso de que puedan distinguir un rango de valores mayor entre el nivel bajo y el alto (por ejemplo, existen pines aue distinguen entre 1024 niveles de tensión diferentes). Además, en ocasiones estos pines se pueden programar para que sean de entrada o de salida, pero otras veces no se pueden programar y tienen un comportamiento fijo e inmutable, por tanto.

Eso de la microcontroladora y los pines está muy bien… pero explícame para qué sirve

Empecemos con un ejemplo muy sencillo. Imagínate que queremos programar un código para que un LED se apague y se encienda de forma cíclica de forma indefinida. Pues con Arduino es muy fácil de programar. Simplemente diseñas un circuito muy básico con un LED, una resistencia y unos cables, montaje que puedes hacer de forma muy inmediata sobre una placa de prototipos. Conectas el LED con un pin de salida determinado, y cierras el circuito uniéndolo con un pin de tierra, sin olvidar la resistencia para proteger al LED y que no se queme.

Una vez montado bien el circuito, por medio de programación puedes hacer algo como «Arduino, ponme 5 V en el pin de salida X durante 2 segundos, luego 0 V en ese mismo pin durante otros 2 segundos y así sucesivamente». Ya que ese pin está unido a un LED, si el circuito está bien construido y todos los componente se encuentran en buen estado, la luz se encenderá y se apagará de forma intermitente e indefinida, hasta que desconectemos la placa de la corriente. A continuación, tienes un ejemplo de lo que se puede hacer con LEDs utilizando la placa Arduino.

Pero, ¿de verdad es útil para el mundo real?

El ejemplo del LED es muy básico, pero Arduino te permite hacer cosas tan complejas como te puedas imaginar. En domótica, de lo cual hablábamos antes, es muy útil porque sus pines son útiles como señal de control para manejar de forma automatizada ciertos elementos. Por ejemplo, un circuito muy sencillo podría constar de un sensor de luz como entrada y el motor de una persiana como salida. Con una placa Arduino, se conecta el sensor a un pin de entraday el motor a un pin de salida.

De esta forma. con un código de programación podrías hacer algo muy sencillo como «si la lectura del sensor de luz sobrepasa un cierto umbral, haz girar el motor para abrir la persiana. Si, por el contrario, la luminosidad queda por debajo del umbral, haz girar el motor para el cierre de la persiana». Como bien hemos dicho, esto se puede hacer todo lo complejo que quieras.

¿Algo más que añadir?

El éxito de Arduino ha hecho que se hayan desarrollado numerosas versiones distintas de placas y expansiones. Hoy en día, es muy sencillo intercomunicar unas placas con otras, ampliar el número de pines con ciertos accesorios e incluso darle más funcionalidades útiles al sistema, ya que existen accesorios para poder comunicar las placas con otros dispositivos por medio de Wi-Fi, Bluetooth o simplemente conexión Ethernet por si quieres utilizar Internet cableado.

Gracias a estas expansiones podrás hacer miles de cosas de forma remota. Imagínate poder gestionar un sistema de calefacción con una placa Arduino, añadirle una expansión con Wi-Fi o Ethernet y conocer la temperatura ambiente de una estancia desde tu móvil en cualquier parte del mundo o, incluso, poder controlar esa misma temperatura a distancia. Incluso, podrías decidir encender o apagar la calefacción, sin estar físicamente en ese lugar. Como puedes ver, la magnitud de lo que puedes hacer con Arduino es gigantesca.

Por último, también es digno destacar que el precio no supone un problema. Hoy en día, aprender a manejar una placa Arduino es muy barato, ya que puedes encontrar kits de iniciación por precios muy razonables con una enorme cantidad de componentes electrónicos que te servirán para crear tus primeros circuitos. Sin duda, estamos en un gran momento para los que quieren ponerse a aprender Arduino, porque por un precio muy asequible podrán adquirir algunas cualidades que le darán una ventaja considerable en el mercado laboral.

¿Qué ventajas me aporta aprender Arduino?

  • ✔ Si solo buscas pasar el rato, puede ser un pasatiempo bastante entretenido, en caso de que te guste jugar un poco con la electrónica.
  • ✔ En un sentido laboral, puede abrirte muchas puertas, ya que Arduino tiene importancia en entornos como la robótica, la domótica y el internet de las cosas.
  • ✔ El aprendizaje de una plataforma como Arduino te puede enseñar a conocer el funcionamiento de sistemas más complejos como las unidades electrónicas de los electrodomésticos, los aviones, los trenes, los barcos o los coches. Por tanto, si quieres trabajar desarrollando algo de ese estilo, comenzar con Arduino es, sin duda, la mejor de las opciones.
  • ✔ Es un hardware muy modular, de tal forma que unas placas se pueden combinar con otras y diseñar sistemas muy complejos. En otras palabras, con unas placas muy baratas y sencillas, podrás hacer proyectos de lo más complejos, tanto si quieres desarrollar algo por tu cuenta como si deseas trabajar en el proyecto de alguien más.
  • ✔ Relacionado con lo anterior, conocer Arduino te podría ser útil para desarrollar proyectos de domótica, robótica o internet de las cosas con lo que podrías incluso crear un negocio donde ofertes soluciones muy personalizadas para tus clientes.

¿Qué cosas aprenderé en un curso de Arduino?

En un curso de Arduino podrás aprender cosas como:

  • ✔ El desarrollo de circuitos electrónicos programables.
  • ✔ Aprenderás a crear sistemas de control que interaccionan con el mundo real, leyendo la información por medio de sensores y ejecutando acciones por medio de actuadores.
  • ✔ Adquirirás las nociones básicas sobre cómo utilizar el entorno de programación de Arduino, donde se escribe el código de programación que más tarde se envía al dispositivo.
  • ✔ Conocerás las necesidades fundamentales de los sistemas embebidos, cuya utilidad se orienta sobre todo a propósitos muy específicos.

Publicado el Deja un comentario

Los puntos clave sobre el lenguaje C

Cursos de programación del lenguaje C

✅ ✅ Has decidido que es la hora de aprender a programar. Lo tienes totalmente claro, estás dispuesto a dar el salto al mundo digital y a un futuro laboral magnífico. Pero no sabes muy bien cuál es el lenguaje que más te conviene. Seguramente has llegado a esta sección porque te ha llamado la atención ese «cursos de C» y habrás oído hablar mil veces de C, de lo maravilloso que es y de lo potente que resulta.

Cursos de programación del lenguaje C

😁😁 Eso sí, aun sabiendo todo eso, no te queda muy claro qué se puede y qué no se puede hacer con él y… después de todo… lo más importante. ¿Debería aprenderme C o debería buscar otra cosa? ¿Me va a resultar útil? ¿Es fácil de aprender? ¿Para qué vale? Intentaremos responder a estas y a otras muchas preguntas en este post. ¡Adelante con todas las claves sobre el lenguaje C!

Resumen sobre las características del lenguaje C

Por si quieres ver directamente las características que definen al lenguaje C y a su aprendizaje, puedes quedarte con este cuadro que te mostramos a continuación.

UtilidadSistemas operativos, robótica, dispositivos embebidos, desarrollo de lenguajes de programación.
DificultadElevada. Necesidad de conocer conceptos fundamentales de los sistemas operativos y otros conceptos de los sistemas informáticos.
CaracterísticasLenguaje de medio nivel. Permite realizar acciones próximas al lenguaje máquina (bajo nivel) y también próximas al lenguaje natural (alto nivel).

¿Por qué aprender C?

C es uno de los lenguajes fundamentales de la programación moderna. Destaca principalmente por dos cosas. La primera, es que se trata de un lenguaje muy rápido. La segunda es que, como consecuencia de la primera, el programador tiene que hacerlo prácticamente todo. Sin embargo, estas características lo convierten en la base de los sistemas operativos que conocemos y de otros lenguajes muy extendidos (como, por ejemplo, ocurre con Java).

💯💁‍♀️ Para que te hagas a la idea de su importancia, el lenguaje C es la base de los sistemas operativos más conocidos, desde Microsoft Windows hasta los sistemas operativos de la familia Linux y, del mismo modo, MacOS. Y ya que Android tiene una base en Linux, este también está desarrollado principalmente en C.

💪💪 Según el top de IEEE Spectrum, una de las listas de referencia para conocer cuáles son los lenguajes de programación más populares, el lenguaje C se situaba en los puestos más altos del ránking, superado únicamente por Python y Java en el año 2020 ocupando, por tanto, la tercera plaza.

💻 En los últimos años ha perdido fuerza debido, entre otras cosas, a ese éxito rotundo de lenguajes como Python, pero sigue siendo un referente e imprescindible en muchas áreas, donde se requiere rapidez y, sobre todo, un conjunto de herramientas capaces de construir sistemas complejos y críticos. En esas áreas nunca será reemplazado ya que, por ejemplo, Java no tiene muchas de las capacidades que C sí tiene.

Bueno… uno vez visto todo esto, comencemos con las sección de preguntas serias.

¿Debería aprender C o buscarme otra cosa?

Pues antes esto la respuesta es un gran DEPENDE. Todo depende de lo que pretendas aprender y a donde quieras orientar tu carrera profesional. C es un lenguaje particularmente complejo de manejar ya que, como bien indicamos hace un momento, el programador lo tiene que hacer todo. Para que lo entiendas, C es un lenguaje de medio nivel… y aquí ya nos estamos metiendo un poco en la parte complicada… pero no te preocupes, es muy sencillo de entender.

Los mejores libros para aprender a programar en C

Por si valoras la opción de aprender C por ti mismo o quieres complementar tu aprendizaje en un curso con un buen libro, aquí te damos algunas ofertas para que lo puedas comprar.

¿Que clase de cosas puede hacer C?

➡️ En C tienes la capacidad de decirle a la máquina cosas muy básicas, de ahí que sea tan potente, porque pudiendo manejar todas las funcionalidades fundamentales, puedes desarrollar cualquier cosa que se te ocurra.

⚠️ ¿Qué es eso de medio nivel? La verdad es que se trata de un término que no a todo el mundo le gusta, pero viene a decir que las instrucciones que tú le das a la máquina con este lenguaje pueden ser bastante próximas al lenguaje natural (es decir, a como tú le darías las órdenes al ordenador si pudieras hablar) pero también puedes hacer cosas muy de bajo nivel, del estilo «llévame este byte que está en la posición X a la posición Y».

↪ Si no has entendido bien, te lo podemos aclarar un poco más. Cuando un lenguaje tiene unas instrucciones muy próximas al lenguaje natural se le llama de alto nivel. Cuando están próximas al nivel de máquina, se llaman de bajo nivel. Como C es una cosa intermedia, que permite ambas cosas, a menudo se le denomina como de medio nivel en la literatura.

Y ahora vayamos al meollo de la cuestión. ¿De qué me serviría a mí aprender C?

  • ✔ Si te gusta todo el tema de los sistemas operativos, C es una fantástica opción. Este lenguaje es la base de todo sistema operativo moderno, dadas las capacidades que tiene (como bien describimos anteriormente).
  • ✔ Si quieres trabajar en el desarrollo de software para dispositivos embebidos, en otras palabras… seguro que has escuchado hablar de Arduino. Para trabajar con él, se utiliza una versión de C/C++ y se trabaja a muy bajo nivel. Todos aquellos aparatos que no sean ordenadores convencionales ni smartphones ni nada parecido y que requieren de un software muy específico… es posible que ahí C sea imprescindible.
  • ✔ En el entorno de la robótica, el lenguaje C es muy importante también. Por ejemplo, los robots LEGO Mindstorms pueden programarse utilizando un entorno llamado «RobotC«.
  • ✔ Si quieres trabajar como desarrollador de lenguajes de programación o en un puesto donde, por ejemplo, te pidan crear un software para convertir un código de un lenguaje a otro de forma automática, C puede ser muy importante. Si quieres saber más al respecto, puedes buscar información sobre software como Flex y Bison.

Como puedes ver, el lenguaje C es muy potente, muy interesante, muy rápido y ofrece una gran variedad de ofertas laborales. Sin embargo, como ya te puedes imaginar, esto lo puede hacer un tanto complejo para aprender.

¿Es fácil de aprender el lenguaje C?

🤔 El aprendizaje de un lenguaje como C está reservado a personas que desean profundizar de manera bastante importante en los fundamentos de la informática. Para manejar C hace falta entender muchos conceptos básicos de lo que son los sistemas operativos.

  • Gestión de la memoria.
  • Manejo de los procesos.
  • Variables estáticas y dinámicas.
  • Llamadas al sistema.
  • Representación de la información a nivel físico, es decir, cómo se representan los datos en un nivel binario.

Además, presenta la cualidad de que no es multiplataforma de por sí, como ocurre con otros lenguajes como Java, si no que hay que programar de maneras distintas según el sistema operativo. Esto no debería ocurrir pero, en ocasiones, algunas funciones que hacen cosas similares no se llaman igual en todos los sistemas operativos.

✔💯 Por tanto, si lo que buscas es programar a un nivel muy bajo y hacer cosas que sirvan de soporte para otros sistemas más complejos, te aseguramos que C es lo que estás buscando.

📚 Para aquellas personas que desean tener una formación sólida en informática sabiendo algo más que un simple lenguaje de programación y evitando estar muy limitado para aprender lenguajes o conceptos nuevos, comenzar con C puede ser un camino duro pero que dará sus frutos.

Una vez que aprendas C serás capaz de adquirir con mucha mayor rapidez habilidades para manejar nuevos lenguajes de programación y para aprender a manejar y comprender cuestiones relacionadas, entre otras cosas, con los sistemas operativos.

⚠️ En resumen, si no estás dispuesto a aprender miles de cosas sobre el sistema operativo y de cómo el software más importante de nuestros ordenadores lleva a cabo sus tareas, lo más probable es que este no sea el lenguaje que buscas. Pero no pasa nada… porque esta es solo una opción entre las muchas que hay, por lo que te invitamos a que sigas visitando nuestra página en busca de más consejos.

¿Qué vas a aprender en un curso de C?

Un curso de C te enseñará los conceptos básicos sobre este lenguaje. Por una parte, que se trata de un lenguaje de medio nivel, es decir, que permite interactuar de una forma bastante directa con las funciones más básicas de los sistemas operativos. Aprenderás que casi todas las variables en C son números enteros (incluidos los booleanos), excepto los números reales.

También te enseñarán los conceptos de memoria dinámica y como trabajar directamente con ella desde las librerías que proporciona el lenguaje (y, de paso, también aprenderás la complejidad que supone para un programador tener la necesidad de gestionar la memoria manualmente). También vas a aprender otras cosas fundamentales como compilar un código de C o como definir un fichero de interfaz para crear módulos. Y si escoges el camino de aprender C, te enfrentarás al temido «Segmentation Fault (Core Dumped)» de cuando haces algo mal pero bueno, no adelantemos acontecimientos.

Algunos consejos para los que tienen claro que van a aprender C

🔋🔋 Para aquellos que tengan claro que quieren ponerse ya manos a la obra y aprender a programar en C, aquí va un pequeño regalo a modo de consejos. Para el desarrollo de programas es preciso tener a tu disposición un buen entorno de programación como Eclipse IDE, NetBeans, Visual Studio Code o entornos más sencillos como Geany o Atom. Hay quien incluso se atreve a programar en un Bloc de Notas o en terminal de comandos, pero los entornos de programación facilitan mucho la tarea a la hora de trabajar.

📍 Y hemos hablado de un concepto clave: el terminal. Si no estás acostumbrado al típico terminal de letras blancas sobre fondo negro vete haciéndote a la idea de que será tu entorno de trabajo. Cuando comiences a programar, no te pienses que vas a hacer programas superchulos con su interfaz gráfica, del estilo como lo que puedes ver en la imagen de arriba. Más bien, te va a dar la sensación de que estás haciendo informática de los años 70. Sin embargo, si quieres programar en C, lo más seguro es que siempre vayas a trabajar en terminal así que… ¡acostúmbrate a trabajar como los profesionales! Más o menos, como lo de la foto que tienes a continuación.

Si vas a programar en C, esta será tu nueva amiga inseparable…

🐧🐧 Por lo general, el desarrollo en C suele realizarse con un sistema operativo de la familia Unix (Linux o MacOS, por ejemplo), ya que se integra mejor con todas las tareas de programación y cuando implican el uso de C, esto no es una excepción. Una de las aproximaciones más interesantes es utilizar un compilador GCC (un software libre y gratuito), que ya viene integrado generalmente con cualquier distribución Linux y que se encarga de convertir el código en C, que entiende el programador, a un fichero binario que entiende la máquina. Este fichero binario será lo que comúnmente denominamos como ejecutable.

¿Te ha quedado todo claro?

😘😘 Gracias por tu visita y esperamos con los brazos abiertos tus valoraciones, comentarios y sugerencias sobre nuestros consejos. Te invitamos a seguir buscando información, si aun lo tienes todo claro y por supuesto podrás hacer preguntas sobre cualquier duda que tengas, pues nosotros estaremos encantados de resolverlas. Si te ha gustado el post, no dudes en compartirlo en tus redes. ¡Hasta la próxima entrada!

Publicado el Deja un comentario

Las claves sobre Java

Cursos de programación de Java

⚠️ Has oído hablar millones de veces sobre Java, pero no te queda muy claro para qué vale o si es útil para tu futuro laboral. En este post, te explicaremos por qué Java es un lenguaje tan utilizado y cuáles son las claves para que decidas si es lo que buscas o no… y de paso, te daremos algunas recomendaciones antes de que te pongas a trabajar con él. ⚠️

👍👍 ¡Empecemos a hablar sobre Java!

Resumen de las características de Java

UtilidadEs un lenguaje de programación utilizado para la creación de aplicaciones empresariales, tanto de escritorio como web.
DificultadMedia. No se requieren conocimientos informáticos de muy bajo nivel, a menos que se desee conocer a fondo el funcionamiento del lenguaje.
CaracterísticasEs un lenguaje orientado a objetos desarrollado con la intención de crear aplicaciones con elementos modulares que se puedan reutilizar y mantener fácilmente.

¿Por qué debería aprender Java?

✅ ✅ Java es uno de los lenguajes más conocidos en el mercado y que más oferta laboral tiene. Utiliza un modelo de programación denominado «orientación a objetos» que lo hace ideal para proyectos empresariales, ya que incentiva la creación de código que se pueda organizar en módulos y sea fácil de mantener a lo largo del tiempo. La respuesta a «¿por qué debería aprender Java?» es sencilla: simplemente, es uno de los lenguajes con mayor demanda laboral tiene. Así que, si te gusta el desarrollo de aplicaciones empresariales y proyectos avanzados, este es el lenguaje que deberías aprender.

Este lenguaje tiene una sintaxis muy similar a C pero su aprendizaje es más sencillo ya que, al contrario que en C, no es necesario que el programador gestione los recursos de memoria, ya que el propio Java dispone de un sistema que se encarga de hacerlo, en un modo totalmente automático. Además, la forma de programa es muy distinta.

Este lenguaje puede utilizarse para desarrollar aplicaciones «standalone», es decir, aquellas que se pueden ejecutar directamente en nuestra máquina (un ejemplo de aplicaciones standalone son el bloc de notas y el explorador de archivos) o bien aplicaciones web, es decir, aquellas a las que se puede acceder directamente por medio de un navegador.

Libros para aprender a programar en Java

Para aprender a programar en Java y adquirir las competencias necesarias para desarrollar aplicaciones empresariales, lo más recomendable es que te interesen por el propio lenguaje complementándolo con el conocimiento de los principales conceptos de programación orientada a objetos y patrones de diseño software. Para ello, te recomendamos una serie de libros por si te interesa aprender Java por esta vía.

¿Qué conocimientos adquiriré aprendiendo Java?

A la hora de aprender Java, primero debes conocer los conceptos básicos sobre orientación a objetos y diseño de la arquitectura software. Esto incluye hablar sobre ideas como el polimorfismo, la herencia, la ligadura dinámica, las interfaces de Java y otros elementos como los mejores entornos de programación orientados a este lenguaje (Eclipse IDE o NetBeans IDE, por ejemplo), sistemas de automatización como Maven o incluso, JUnit o cualquier proyecto similar que te permitirá hacer pruebas para verificar el correcto funcionamiento de tu código.

Java se caracteriza por ser un lenguaje que genera una gran cantidad de archivos cada vez que se desea llevar a cabo un proyecto. Es por ello que los entornos de programación son tan importantes y prácticamente imprescindibles para que se encarguen de gestionar todos los aspectos que tengan que ver con eso.

Algunos consejos para crear tus proyectos inteligentemente

Del mismo modo, también resulta muy interesante aprender a utilizar un sistema de gestión de versiones como puede ser Git o SVN (aunque el primero es, hoy en día, la opción mejor valorada por sus usuarios). La utilización de un gestor de versiones te ayudará a registrar los cambios que hagas en tu código y recuperar una versión más antigua en caso de que hayas hecho algo que no deberías.

Cabe destacar que Git te permite guardar los cambios de tu código y recuperarlos, pero necesitas una plataforma donde se almacenen estos datos de forma física. Para ello, puedes hacerte una cuenta de GitHub o GitLab de forma gratuita, la cual te permite crear una gran cantidad de proyectos. Además, gracias a este tipo de plataformas podrás compartir tu código de forma pública si lo deseas, lo cual puede ser una buena carta de presentación a la hora de afrontar una entrevista de trabajo o para añadir a tus redes sociales y que más empresas se interesen por ti.