Enmascaramiento de imágenes en OpenCV

Sahil Bhosale 15 febrero 2024
Enmascaramiento de imágenes en OpenCV

Si queremos filtrar alguna parte de la imagen y luego combinar esta parte filtrada con otra imagen, entonces esto se puede hacer usando enmascaramiento. En OpenCV, el operador Bitwise AND se usa para combinar dos imágenes diferentes en una, o puede combinar algunas partes de una imagen en otra.

Bitwise AND generalmente calcula la combinación lógica bit a bit por elemento de dos matrices/escalares/imágenes. En este artículo, veremos cómo aplicar máscaras en una imagen usando el operador Bitwise AND de la biblioteca OpenCV.

Realizar enmascaramiento en OpenCV usando el operador bit a bit AND

Los operadores bit a bit se utilizan en OpenCV para que podamos extraer o filtrar la parte de una imagen, retratando la imagen y operando con ROI no rectangulares (Región de interés). Para realizar la operación Bitwise AND en OpenCV, usamos el método bitwise_and().

La sintaxis de bitwise_and() es la siguiente.

cv.bitwise_and(img_array_1, img_array_2, destination_array, masking)

El método bitwise_and() toma cuatro argumentos:

  1. img_array_1: Datos de la imagen 1 en formato array.
  2. img_array_2: Datos de la imagen 2 en formato array.
  3. destination_array: Imagen de salida con el mismo tamaño y tipo que la matriz de entrada. Este es un parámetro opcional.
  4. masking: Es la operación de enmascaramiento que se realiza sobre la imagen resultante. Este es un parámetro opcional.

Veamos cómo funciona el enmascaramiento usando bitwise_and() con la ayuda del siguiente ejemplo.

Supongamos que tenemos dos imágenes, una imagen de un logotipo y otra de un automóvil, y necesitamos agregar el logotipo en la parte superior izquierda de la imagen del automóvil. Entonces, para lograr esto, escribiremos el siguiente código en Python usando OpenCV.

Primero, necesitamos leer las imágenes tanto del logotipo como de la imagen del automóvil y luego asignarlas a las variables img1 e img2, respectivamente. Al enmascarar, usaremos el ROI para aplicar o mostrar el logotipo en el lado superior izquierdo de la imagen del automóvil.

Para ello, extraeremos los datos de row, cols y channels de img2, nuestro logo. Como queremos colocar este logotipo en la esquina superior izquierda de la imagen del automóvil, aplicaremos las “filas” y “columnas” de img2 en las coordenadas img1 (0,0), como se muestra a continuación.

Fragmento de código:

# import opencv
import cv2 as cv

# Loading images
img1 = cv.imread("car.jpg")
img2 = cv.imread("logo.png")

# We want to put the logo on the top-left corner, so we create ROI
rows, cols, channels = img2.shape
roi = img1[0:rows, 0:cols]

# Now create a mask of the logo and create its inverse mask, also
img2gray = cv.cvtColor(img2, cv.COLOR_BGR2GRAY)
ret, mask = cv.threshold(img2gray, 10, 255, cv.THRESH_BINARY)
mask_inv = cv.bitwise_not(mask)

# Now black out the area of the logo in ROI
img1_bg = cv.bitwise_and(roi, roi, mask=mask_inv)

# Take only the region of the logo from the logo image.
img2_fg = cv.bitwise_and(img2, img2, mask=mask)

# Put logo in ROI and modify the main image
dst = cv.add(img1_bg, img2_fg)
img1[0:rows, 0:cols] = dst

cv.imshow("mask", mask)
cv.imshow("inv_mask", mask_inv)
cv.imshow("img1_bg", img1_bg)
cv.imshow("img2_fg", img2_fg)
cv.imshow("Final image", img1)
cv.waitKey(0)
cv.destroyAllWindows()

Después de esto, tenemos que crear la máscara y la máscara inversa del logotipo. Para esto, inicialmente cambiamos el color de fondo del logo a gris y lo usamos para hacer la máscara y la imagen de la máscara inversa como mask y mask_inv.

Para cambiar el color de fondo de la imagen, usaremos el método cvtColor(), y para crear una máscara, usaremos el método threshold(). Finalmente, usaremos el bitwise_not() para invertir la imagen.

También podemos usar la función imshow() en las imágenes mask y mask_inv para examinar qué ha cambiado durante el enmascaramiento.

Ahora oscurecemos el área del logotipo en ROI y hacemos bitwise_and() para obtener el fondo del logotipo, es decir, img2. De manera similar, tomamos solo el logotipo de la imagen del logotipo y hacemos bitwise_and() para obtener el primer plano de la imagen del automóvil, es decir, img1.

Aquí, también podemos usar la función imshow() en las imágenes img1 (imagen del automóvil) e img2 (imagen del logotipo) para ver qué cosas se han cambiado.

Ahora, agregamos tanto img1 como img2, por lo que obtenemos el logotipo con el fondo de un automóvil en ROI. Luego ponemos esta imagen de salida en dst.

Producción:

Enmascaramiento de imágenes en la salida final de OpenCV

Luego agregamos el dst en la imagen completa del automóvil y obtenemos el resultado final usando imshow(). Así es como usamos el ROI para obtener una parte específica de la imagen y agregarla a otra imagen para obtener la imagen final.

Sahil Bhosale avatar Sahil Bhosale avatar

Sahil is a full-stack developer who loves to build software. He likes to share his knowledge by writing technical articles and helping clients by working with them as freelance software engineer and technical writer on Upwork.

LinkedIn

Artículo relacionado - Python OpenCV