CAMBIA EL FONDO de una imagen o escena ?️ | Python – MediaPipe – OpenCV

Por Administrador

¿Cómo cambiar el fondo de una escena usando Python, OpenCV y… MediaPipe?. ? En este tutorial te muestro como puedes hacerlo. Podrás cambiar el fondo con una imagen, una imagen borrosa, y un video. ¡Anímate a probarlo!

CONTENIDO

Cambiar el fondo de una escena

  • Procedimiento para construir el cambio de fondo de escena
  • ¡Vamos con la programación!

Cambiar el fondo de una escena

Figura 1: Ejemplo del cambio de fondo. (Izq) Imagen de entrada, (Der) imagen de salida.

En el tutorial de hoy veremos como cambiar el fondo de una escena, y vamos a tratar de hacer algo similar a lo que podemos encontrarnos en Zoom cuando realizamos una videollamada. Es decir, en ella podemos cambiar el fondo de la escena sin afectar a las personas más prominentes que allí aparezcan.

Para poder realizar esta aplicación vamos a usar Python, OpenCV, numpy y MediaPipe. Específicamente de MediaPipe usaremos Selfie Segmentation, que es una de las soluciones que habíamos visto en el tutorial anterior. Este nos va a permitir obtener una máscara donde la sección más clara representa a la o las personas más prominentes presentes en la imagen, mientras que los pixeles más oscuros representan al fondo de la escena.

Figura 2: Ejemplo del uso de MediaPipe Selfie Segmentation.

Procedimiento para construir el cambio de fondo de escena

Figura 3: Procedimiento que vamos a realizar para realizar el cambio de fondo.

En la figura 3 podemos ver el procedimiento que vamos a realizar. Empezamos con en video de entrada al cual le aplicaremos MediaPipe Selfie Segmentation, de donde obtendremos una máscara binaria cuya sección en blanco representa a la o las personas presentes. A esta máscara la invertiremos, ya que esto nos servirá para ubicar en la parte blanca el fondo de la imagen.

Una vez que tenemos estas imágenes binarias vamos a proceder a ubicar en la parte blanca por un lado a la persona a color, y por otro lado el fondo de la imagen a color. Finalmente sumaremos estas dos imágenes para obtener el cambio de fondo de la escena.

En este tutorial estaremos usando operadores bitwise por lo que te recomiendo que le eches un vistazo a este tutorial: Operadores BITWISE (AND-OR-NOT-XOR) con OpenCV y Python

¡Vamos con la programación!

Para una explicación más detallada del programa que veremos a continuación, por favor dirígete al videotutorial de mi canal.

NOTA

En el videotutorial podrás encontrar como cambiar el fondo de la escena con:

  • Una imagen creada con OpenCV.
  • Una imagen leída, y además como difuminarla.
  • Un video como fondo.

El siguiente programa contiene las líneas de código realizadas en videotutorial.

import cv2
import mediapipe as mp
import numpy as np

mp_selfie_segmentation = mp.solutions.selfie_segmentation

# Video de entrada
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)

# Video que se ubica en el fondo
video_name = "video.extensión"
cap2 = cv2.VideoCapture(video_name)

# Color de fondo de escena
BG_COLOR = (219, 203, 255)

with mp_selfie_segmentation.SelfieSegmentation(
     model_selection=1) as selfie_segmentation:

     while True:
          # Lectura del video de entrada
          ret, frame = cap.read()
          if ret == False:
               break

          # Lectura del video que se ubica en el fondo
          ret2, bg_image = cap2.read()
          if ret2 == False:
               cap2 = cv2.VideoCapture(video_name)
               ret2, bg_image = cap2.read()

          # Transformar los fotogramas de BGR a RGB y
          # aplicación de MediaPipe Selfie Segmentation
          frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
          results = selfie_segmentation.process(frame_rgb)

          # Obtener imagen binaria
          _, th = cv2.threshold(results.segmentation_mask, 0.75, 255, cv2.THRESH_BINARY)

          # Cambio de tipo de dato para poder usarlo con OpenCV
          # e invertir la máscara
          th = th.astype(np.uint8)
          th = cv2.medianBlur(th, 13)
          th_inv = cv2.bitwise_not(th)

          # Background
          #bg_image = np.ones(frame.shape, dtype=np.uint8)
          #bg_image[:] = BG_COLOR
          #bg_image = cv2.imread("image_0001.jpg")
          #bg_image = cv2.GaussianBlur(bg_image, (15, 15), 0)
          bg = cv2.bitwise_and(bg_image, bg_image, mask=th_inv)

          # Foreground
          fg = cv2.bitwise_and(frame, frame, mask=th)

          # Background + Foreground
          output_image = cv2.add(bg, fg)

          # Visualización
          #cv2.imshow("Th", th)
          #cv2.imshow("th_inv", th_inv)
          #cv2.imshow("bg", bg)
          #cv2.imshow("fg", fg)
          cv2.imshow("output_image", output_image)
          cv2.imshow("Frame", frame)

          if cv2.waitKey(1) & 0xFF == 27:
               break

cap.release()
cv2.destroyAllWindows()

Espero que te haya gustado el videotutorial y también espero que te animes a probarlo. ¡Ten un lindo día!. 🙂