Umbralización simple con OpenCV y Python | Minicurso OpenCV – Parte 7
Bienvenidos al séptimo artículo del minicurso de Visión por Computador con OpenCV en Python. En el artículo anterior vimos 7 aspectos a tener claro cuando empezamos a trabajar con OpenCV. Ahora vamos a empezar con la práctica y nos introduciremos en la umbralización simple, una técnica que nos va a permitir diferenciar áreas dentro de una imagen. Así que ¡empecemos!
¿Qué aprenderás en este artículo?
- Qué es la umbralización simple y para qué se utiliza en visión por computador
- Cómo aplicar la umbralización simple en un programa
¿Qué es la umbralización simple?
Analicemos las siguiente imagen:

Al verla podemos darnos cuenta que tenemos una moneda sobre una superficie de color negro. Para nosotros es muy sencillo identificar dónde empieza la moneda y dónde termina el fondo. Sin embargo, el computador no identifica monedas o el lugar sobre el que se encuentran, lo único que ve es una matriz de números.

Para que el computador pueda empezar a entender el contenido de la imagen, necesitamos presentársela de una forma más simple. Una opción muy común es una imagen binaria, es decir una imagen en blanco y negro en donde:
- El color blanco represente la moneda o área de interés
- El negro represente el fondo
De esta manera el computador sabrá en dónde está el fondo y dónde la moneda, sin embargo ahora surge una pregunta: ¿cómo llegamos de una imagen a color a una imagen binaria?

El primer paso para conseguir la imagen binaria es pasarla de color a escala de grises. ¿Por qué hacemos esto?
Porque una imagen a color tiene tres canales: rojo, verde y azul. Y eso es más información de la que necesitamos para este problema.
En cambio, una imagen en escala de grises tiene un solo valor por píxel, que representa su intensidad, es decir, qué tan claro u oscuro es. El cero representa el color negro, 255 el color blanco y los valores intermedios son los distintos tonos de gris.
Por ejemplo, un gris más claro estará más cerca de 255, mientras que un gris más oscuro estará más cerca de 0.
Una vez que tenemos la imagen en escala de grises debemos elegir un valor entre 0 y 255 que permita separar el fondo del objeto. A este valor lo llamamos umbral. De este modo, los píxeles que tengan un valor mayor al umbral pasarán a ser blancos, y los que tengan un valor menor pasarán a ser negros. A esto se le llama umbralización simple.

¡Vamos con la programación!
¿Cómo aplicar umbralización simple con OpenCV?
Para llevar a cabo esta práctica usaremos la siguiente imagen de entada:

El objetivo será encontrar el umbral que permita diferenciar los clips del fondo de la imagen.
Bien, ahora ¡vamos con el código!
import cv2
# Leer la imagen, convertirla a escala de grises y suavizarla
image = cv2.imread("01_image.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gblur = cv2.GaussianBlur(gray, (5, 5), 0)
Línea 1: Importamos OpenCV con import cv2.
Línea 4: Leemos la imagen de entrada con cv2.imread().
Línea 5: Recordemos que OpenCV lee una imagen por defecto en BGR, así que para pasarla a escala de grises usaremos la función cv2.cvtColor(), indicamos la imagen que vamos a transformar y luego especificamos cv2.COLOR_BGR2GRAY.
Línea 6: Aplicamos suavizado a la imagen, y para ello usamos la función cv2.GaussianBlur(). En OpenCV existen varias técnicas de suavizado con las que podrías experimentar, así como distintos tamaños de kernel. En este caso estamos usando un kernel de 5×5, es decir, cada píxel se suaviza teniendo en cuenta este número de vecinos cercanos.
¿Y para qué sirve el suavizado de imágenes?
Su objetivo principal es reducir pequeñas variaciones o ruido en la imagen, de manera que los cambios entre píxeles sean más suaves. El ruido puede aparecer por diferentes razones, como: la cámara, la iluminación o incluso la compresión de la imagen. Al aplicar este suavizado, preparamos mejor la imagen para pasos posteriores.
Veamos las imágenes a escala de grises y suavizada:

Ahora bien, sobre la imagen suavizada vamos a aplicar la umbralización:
# Aplicar umbralización simple _, binary = cv2.threshold(gblur, 180, 255, cv2.THRESH_BINARY) _, binary_inv = cv2.threshold(gblur, 180, 255, cv2.THRESH_BINARY_INV)
Línea 9 y 10: Con cv2.threshold() aplicamos umbralización simple.
En la línea 9 usamos cv2.threshold(). En primer lugar especificamos la imagen suavizada, luego el umbral para comparar cada uno de los valores de los píxeles. Después de prueba y error se ha encontrado que 180 es un buen valor para diferenciar los objetos del fondo. Luego especificamos 255 para que todos los píxeles que estén por encima de 180 se les asigne 255, y el resto 0.
Con cv2.THRESH_BINARY especificamos cómo se aplica el umbral, es decir, que todos los píxeles cuyo valor sea mayor que 180 pasarán a blanco (255), mientras que los demás pasarán a negro (0). De esta manera construimos una imagen binaria donde separamos claramente objeto y fondo.
Como salida obtenemos el valor del umbral utilizado y la imagen resultante. Pero como lo escogimos manualmente, ignoramos ese primer valor usando _, mientras que en binary almacenamos la imagen binaria.
En la línea 10 realizamos algo parecido. Pero en este caso usamos cv2.THRESH_BINARY_INV. Esto hará que el comportamiento se invierta: los píxeles mayores al umbral pasarán a negro (0), y los menores o iguales pasarán a blanco (255). En otras palabras, estamos invirtiendo los colores de la imagen binaria.
# Visualizar resultados
cv2.imshow("Imagen original", image)
cv2.imshow("gray", gray)
cv2.imshow("gblur", gblur)
cv2.imshow("binary", binary)
cv2.imshow("binary_inv", binary_inv)
cv2.waitKey(0)
cv2.destroyAllWindows()
De la línea 13 a 20 visualizamos las imágenes según el proceso que hemos llevado a cabo, para finalmente esperar a que se presione una tecla y cerrar las ventanas.
Veamos el resultado:

En la imagen de la izquierda (binary) vemos el resultado de aplicar cv2.THRESH_BINARY. En este caso, todos los píxeles con un valor mayor a 180 pasan a 255 (blanco), mientras que los que tienen un valor menor o igual a 180 pasan a 0 (negro). Como el fondo es mucho más claro que los clips, la mayoría de sus píxeles superan el umbral y por eso aparece completamente blanco.
En la imagen de la derecha (binary_inv) aplicamos cv2.THRESH_BINARY_INV, que invierte el comportamiento anterior. Aquí los píxeles mayores a 180 pasan a negro y los menores o iguales pasan a blanco. Esto provoca que el fondo ahora sea negro y los clips aparezcan en blanco.
Esta diferencia es muy importante en visión por computador. En muchos procesos posteriores, como la detección de contornos o el conteo de objetos, normalmente se espera que los objetos de interés estén en blanco y el fondo en negro.
Gracias por haber llegado hasta aquí. Espero que este contenido te haya sido útil. Si te quedaste con alguna duda o te gustaría que profundicemos en algún punto, puedes dejarlo en los comentarios.
Nos vemos en el siguiente artículo. 😊




