Segmentación de imágenes en OpenCV

Manav Narula 30 enero 2023
  1. Segmentación de imágenes usando opencv en Python
  2. Use el algoritmo GrabCut para la segmentación de imágenes usando opencv
  3. Use la detección de color para la segmentación de imágenes usando opencv
  4. Conclusión
Segmentación de imágenes en OpenCV

El procesamiento de imágenes es un paso crucial en las tareas de visión artificial. En Python, podemos usar la biblioteca opencv para implementar varias técnicas de procesamiento de imágenes usando diferentes objetos y métodos.

Este tutorial demostrará cómo realizar la segmentación de imágenes utilizando opencv en Python.

Segmentación de imágenes usando opencv en Python

La segmentación de imágenes se refiere al proceso de dividir una imagen dada en varias partes.

Agregamos curvas que unen los puntos a lo largo del límite de las partes segmentadas. Estas curvas se denominan contornos.

La segmentación de imágenes es muy útil en Computer Vision y tiene muchas aplicaciones en la vida real. Podemos usar esta técnica para segmentar partes de una imagen para clasificar varios objetos.

Se pueden usar varios métodos disponibles para la segmentación de imágenes usando opencv en Python.

El método principal que difiere en cada técnica de segmentación de imágenes suele basarse en el criterio de la imagen segmentada. Podemos tener una segmentación de imágenes basada en la detección de algunos colores, algoritmos predefinidos como el algoritmo Watershed, detección de bordes e incluso seleccionar las porciones segmentadas en función de las entradas del usuario.

Discutiremos algunos de estos métodos en las siguientes secciones.

Use el algoritmo GrabCut para la segmentación de imágenes usando opencv

Este método requiere la interacción del usuario con el mouse y el teclado. La biblioteca opencv incorporada tiene objetos y métodos que pueden leer la entrada del usuario desde el mouse y el teclado.

El algoritmo GrabCut es una herramienta muy sencilla y útil para la segmentación de imágenes. En esta técnica, usamos la entrada del usuario para seleccionar alguna región de una imagen determinada.

Este algoritmo detecta automáticamente el primer plano y el fondo de la parte segmentada y podemos mostrarlos.

Podemos usar la función grabCut() de la biblioteca opencv para implementar este algoritmo. Pasaremos la imagen junto con el cuadro de la región seleccionada dentro de esta función de segmentación de imágenes.

Consulte el siguiente código para ver un ejemplo.

import cv2
import numpy as np


def algo_grabcut(img, bounding_box):
    seg = np.zeros(img.shape[:2], np.uint8)
    x, y, width, height = bounding_box
    seg[y : y + height, x : x + width] = 1
    background_mdl = np.zeros((1, 65), np.float64)
    foreground_mdl = np.zeros((1, 65), np.float64)

    cv2.grabCut(
        img, seg, bounding_box, background_mdl, foreground_mdl, 5, cv2.GC_INIT_WITH_RECT
    )

    mask_new = np.where((seg == 2) | (seg == 0), 0, 1).astype("uint8")
    img = img * mask_new[:, :, np.newaxis]
    cv2.imshow("Output", img)


def box_draw(click, x, y, flag_param, parameters):
    global x_pt, y_pt, drawing, topleft_pt, bottomright_pt, img

    if click == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        x_pt, y_pt = x, y

    elif click == cv2.EVENT_MOUSEMOVE:
        if drawing:
            topleft_pt, bottomright_pt = (x_pt, y_pt), (x, y)
            image[y_pt:y, x_pt:x] = 255 - img[y_pt:y, x_pt:x]
            cv2.rectangle(image, topleft_pt, bottomright_pt, (0, 255, 0), 2)

    elif click == cv2.EVENT_LBUTTONUP:
        drawing = False
        topleft_pt, bottomright_pt = (x_pt, y_pt), (x, y)
        image[y_pt:y, x_pt:x] = 255 - image[y_pt:y, x_pt:x]
        cv2.rectangle(image, topleft_pt, bottomright_pt, (0, 255, 0), 2)
        bounding_box = (x_pt, y_pt, x - x_pt, y - y_pt)

        algo_grabcut(img, bounding_box)


drawing = False
topleft_pt, bottomright_pt = (-1, -1), (-1, -1)

img = cv2.imread("img4.jpg")
img = cv2.resize(img, (500, 500))
image = img.copy()
cv2.namedWindow("Frame")
cv2.setMouseCallback("Frame", box_draw)

while True:
    cv2.imshow("Frame", image)
    ch = cv2.waitKey(1)
    if ch == 32:
        break

cv2.destroyAllWindows()

Producción:

región seleccionada del algoritmo Grabcut

Imagen segmentada usando el algoritmo GrabCut

Entendamos lo que está sucediendo en el ejemplo anterior.

La función box_draw() lee la interacción del usuario con el mouse para seleccionar la región para la segmentación de la imagen. El cuadro y la imagen se pasan a la función algo_grabcut() que toma la imagen y crea la máscara binaria para la imagen segmentada.

Usamos esta máscara y mostramos el primer plano de la porción segmentada.

Use la detección de color para la segmentación de imágenes usando opencv

En Python, podemos usar el opencv para la detección de color. Hay diferentes espacios de color disponibles para que una imagen represente sus colores.

Para nuestro caso, usaremos el espacio de color HSV para determinar los rangos para el color dado.

Usaremos diferentes colores para la segmentación de imágenes. Creamos un rango para un color dado y usamos la función inRange() de la biblioteca opencv para detectar objetos que coincidan con este color.

Esto devuelve una máscara binaria. Luego refinamos esta máscara y agregamos contornos a esta parte detectada.

Como se discutió anteriormente, los contornos son las curvas en los límites de la parte segmentada. Usaremos la función findContours() para encontrar los bordes usando la máscara creada y luego dibujaremos estos contornos con la función drawContours().

Vea el código a continuación.

import cv2
import numpy as np

img = cv2.imread("img4.jpg")
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
bound_lower = np.array([36, 25, 25])
bound_upper = np.array([70, 255, 255])

mask_green = cv2.inRange(hsv_img, bound_lower, bound_upper)
kernel = np.ones((7, 7), np.uint8)

mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_CLOSE, kernel)
mask_green = cv2.morphologyEx(mask_green, cv2.MORPH_OPEN, kernel)

seg_img = cv2.bitwise_and(img, img, mask=mask_green)
contours, hier = cv2.findContours(
    mask_green.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
output = cv2.drawContours(seg_img, contours, -1, (0, 0, 255), 3)

cv2.imshow("Result", seg_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Producción:

Segmentación de imágenes mediante detección de color

En el código anterior, segmentamos objetos verdes de una imagen dada. Primero, convertimos la imagen al espacio de color HSV usando la función cvtColor.

Luego procedemos a crear la máscara que almacena el color detectado. También eliminamos cualquier ruido no deseado de esta máscara.

Luego dibujamos los contornos del segmento detectado y lo mostramos. La función waitKey() evita que la ventana de la imagen se cierre automáticamente.

Espera a que el usuario presione alguna tecla y luego lo cierra.

Conclusión

En este tutorial, discutimos la segmentación de imágenes usando la biblioteca opencv de Python. También implementamos algunas técnicas para esto, aunque son posibles muchas más.

Discutimos los conceptos básicos detrás de la segmentación de imágenes y cuál será el enfoque y el resultado final en cada método.

Discutimos dos métodos en detalle. Primero, implementamos el algoritmo GrabCut.

En este algoritmo, el usuario selecciona una región que quiere usar para la segmentación. Desde esta porción, detectamos los objetos de primer plano y los mostramos.

En la segunda técnica, utilizamos detección de color. Detectamos objetos de color verde.

En este tipo de segmentación, convertimos la imagen al espacio de color dado y usamos los rangos de color de este modelo para detectar colores usando la función inRange(). Usamos esta máscara para segmentar imágenes y dibujar contornos alrededor de los bordes.

Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn