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

What will we cover in this tutorial?

  1. Understand why it is difficult for a computer program to identify the background.
  2. How we can make a simple approach to identify the background.
  3. A simple pipeline to extract the foreground automatically in a live video stream.
  4. A full implementation of it in Python using OpenCV.
  5. A live example of the implementation in action.

This is not a perfect solution, but you will have it running in less than 10 minutes.

Step 1: Why is it difficult to identify background?

For us humans, it is not a difficult task to identify the background. 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.

This is the core of computer vision that deals with how computers can gain high-level understanding from digital images or videos.

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 in the picture and assume they are part of the foreground 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?

Step 2: How to solve it simple?

Good question. How do we identify what is part of the background and what is part of the foreground?

It depends.

  • 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.

Step 3: 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 principle behind the above approach is as follows. We assume that the foreground will have a medium to high saturation 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.

Step 4: The full code that implements the blurring effect on a live webcam stream.

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()

Step 5: A live example of the implementation of the flow

A result can be seen in the video here.

2 Replies to “OpenCV + Python: A Simple Approach to Blur the Background from Webcam”

Leave a Reply