OpenCV + Python: A Simple Approach to Blur the Background from Webcam

Why is it difficult to identify background?

It is not a difficult task to identify the background for a human, so why is it difficult for a computer? Well, it needs to identify what is part of the foreground, and intended to be part of the picture, and what is part of the of the background and therefore irrelevant for the picture.

Challenges like these are difficult for computer, while they seem obvious for humans. One approach could be to use machine learning and identify all humans on the picture and assume they are part of the picture. But still, that might not be right either. People can be in the background of the picture and not relevant. Like this situation.

Are all the humans part of the foreground?

How to solve it simple?

Good question. How do we identify what is background and what is part of the foreground? It depends on the use case.

  • If we only focus on one picture, it can be done manually.
  • On the other hand, if we need to do it on a live stream, we need something automating the process.
  • How important is it if it is not accurate.
    • Is it a conference call where you just want to hide the mess in the background?
    • Or do really important that nothing get’s out except what you define as foreground.

There are more things to consider that the above. It just gives you an idea that it is not that simple to answer.

Here we will assume that we need to process it fast and it is just to hide your background.

We would like something that can go from this.

With background

To this in a live stream from a webcam.

Blurred background

We are not aiming for the perfect, but for something simple that can be used to blur out the background including details like the writing in the background.

The overall process for blurring out the background

We will use the following pipeline of blurring out the background of an image.

  1. Capture the frame from the webcam.
  2. Convert it to HSV color space (see this tutorial for details on why?)
  3. Make a mask to get pixels of medium to high saturation and value (it seems to capture the foreground, as the background has lower saturation and value in the HSV color space.
  4. Create a blurred image frame.
  5. Combine the blurred with original frame based on the mask.
  6. Show the new combined frame.

The key thing to notice is that our assumption is that foreground things will have a medium til high saturation and value in the HSV color space. This is obviously not correct for all cases, but as the example will show, it will do a decent job in many cases.

The code that implements it

The code is available here.

import cv2
import time
import numpy as np


# Get the webcam
cap = cv2.VideoCapture(0)

# Time is just used to get the Frames Per Second (FPS)
last_time = time.time()
while True:
    # Step 1: Capture the frame
    _, frame = cap.read()

    # Step 2: Convert to the HSV color space
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    # Step 3: Create a mask based on medium to high Saturation and Value
    # - These values can be changed (the lower ones) to fit your environment
    mask = cv2.inRange(hsv, (0, 75, 40), (180, 255, 255))
    # We need a to copy the mask 3 times to fit the frames
    mask_3d = np.repeat(mask[:, :, np.newaxis], 3, axis=2)
    # Step 4: Create a blurred frame using Gaussian blur
    blurred_frame = cv2.GaussianBlur(frame, (25, 25), 0)
    # Step 5: Combine the original with the blurred frame based on mask
    frame = np.where(mask_3d == (255, 255, 255), frame, blurred_frame)

    # Add a FPS label to image
    text = f"FPS: {int(1 / (time.time() - last_time))}"
    last_time = time.time()
    cv2.putText(frame, text, (10, 20), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 2)

    # Step 6: Show the frame with blurred background
    cv2.imshow("Webcam", frame)
    # If q is pressed terminate
    if cv2.waitKey(1) == ord('q'):
        break

# Release and destroy all windows
cap.release()
cv2.destroyAllWindows()

A result can be seen in the video here.

Leave a Reply