Face and Background Blurring with OpenCV in Python

Sometimes blurring and anonymizing faces might be required not to recognize identities in the public photos as Google does in its street view feature. And sometimes we need to blur the background of an image to focus on facial area well. The both case actually require same procedures. In this post, we are going to mention how to handle face and background blurring with OpenCV in Python.

Anonymous in Mr. Robot
Objective

We will be able to apply face or background blurring even for real time videos at the end of this blog post.


🙋‍♂️ You may consider to enroll my top-rated machine learning course on Udemy

Decision Trees for Machine Learning

Face detection

The both face and background blurring requires face detection first. The most common face detectors are opencv haar cascade, SSD, Dlib and MTCNN. Here, SSD is the fastest and MTCNN is the most robust. You can watch the detection performance of those detectors in the following video.

Herein, you can run those face detectors with a single line of code within deepface. The following video shows how to use those detectors.

Generic blurring function

We are going to use the Gaussian Blur function of opencv. The function expects the raw image and Gaussian kernel size respectively. Here, kernel size must be odd. That’s why, we will subtract 1 if it is even number. Besides, I calculated the kernel size with the ratio of image size and factor variable. Here, the less factor is, the more blurred face. On the other hand, the less factor is, the more processing time.

def blur_img(img, factor = 20):
   kW = int(img.shape[1] / factor)
   kH = int(img.shape[0] / factor)
   
   #ensure the shape of the kernel is odd
   if kW % 2 == 0: kW = kW - 1
   if kH % 2 == 0: kH = kH - 1
   
   blurred_img = cv2.GaussianBlur(img, (kW, kH), 0)
   return blurred_img

Here, you can see the how factor size impacts the blurring in the following images.

Blurring with different factors
Blurring the background

We need to blur the background the focus on facial area well. We firstly blur the base image. Secondly, we detected the face in the base image. Then, we put the detected face to the base image.

img = cv2.imread("deepface/tests/dataset/img1.jpg")
blurred_img = blur_img(img, factor = 10)

face_detector_path = "haarcascade_frontalface_default.xml"
faces = face_detector.detectMultiScale(img, 1.3, 5)

for x, y, w, h in faces:
   detected_face = img[int(y):int(y+h), int(x):int(x+w)]
   blurred_img[y:y+h, x:x+w] = detected_face

plt.imshow(blurred_img[:,:,::-1])

This is the result of background blurring

Background blurring
Blurring the face

We will blur the detected face and put it into the base image.

img = cv2.imread("deepface/tests/dataset/img1.jpg")

face_detector_path = "haarcascade_frontalface_default.xml"
faces = face_detector.detectMultiScale(img, 1.3, 5)

for x, y, w, h in faces:
   detected_face = img[int(y):int(y+h), int(x):int(x+w)]
   detected_face_blurred = blur_img(detected_face, factor = 3)
   img[y:y+h, x:x+w] = detected_face_blurred

plt.imshow(img[:,:,::-1])

This is the result of face blurring. You cannot really identify the Angelina Jolie.





Face blurring
Pixelated blurring

We can do face blurring in a more elegant way! We will separate the detected face into smaller pieces, and apply Gaussian blur to those small pieces.

I created the following function to separate and image into smaller pieces.

def extract_indexes(length, step_size):
   indexes = []
   
   cycles = int(length / step_size)
   
   for i in range(cycles):
       begin = i * step_size; end = i * step_size+step_size
       #print(i, ". [",begin,", ",end,")")
   
       index = []
       index.append(begin)
       index.append(end)
       indexes.append(index)
   
       if begin >= length: break
       if end >length: end = length
   
   if end < length:
       #print(i+1,". [", end,", ",length,")")
       index = []
       index.append(end)
       index.append(length)
       indexes.append(index)
   
   return indexes

Then, I will build a for loop to process smaller pieces of detected face. In each iteration, I will call generic blur function to blur the small piece. Finally, put those small blurred pieces into the raw image.

pixelated_face = detected_face.copy()

width = pixelated_face.shape[0]
height = pixelated_face.shape[1]

step_size = 80

for wi in extract_indexes(width, step_size):
   for hi in extract_indexes(height, step_size):
      detected_face_area = detected_face[wi[0]:wi[1], hi[0]:hi[1]]
      if detected_face_area.shape[0] > 0 and detected_face_area.shape[1] > 0:
        detected_face_area = blur_img(detected_face_area, factor = 0.5)
        pixelated_face[wi[0]:wi[1], hi[0]:hi[1]] = detected_face_area</code></pre>

img[y:y+h, x:x+w] = pixelated_face
plt.imshow(base_img[:,:,::-1])

This is the result of pixelated face. It seems more elegant and you cannot still identify Angelina Jolie.

Pixelated face
Real time implementation

We can run blurring in real time as well. Here, you can find the source code of this implementation. You can set case to background, face or pixelated face. Besides, opencv haar cascade and mtcnn can be set in the code.

The following video show the blurring the testimony video of Mark Zuckerberg with MTCNN and pixelated pair. BTW, I set the confidence score of face detection to 90%. You can decrease this value to detect faces in some frames hadn’t been detected.

case = 'pixelated'

Alternatively, you can blur all the facial area as well. You need to set the case variable to face in this case.

case = 'face'

This is the blurring of all face instead of pixelated one.

Future work

Dlib offers facial landmarks detector for 68 points including  jaw and chin, eyes and eyebrows, inner and outer area of lips and nose. In this way, we can blur the face or background more sensitively. Besides, we can remove the outer area of a face to feed noiseless images to a face recognition pipeline.

Conclusion

So, we have mentioned how to blur the both face and background of an given image with OpenCV in Python. We just need basically face detection feature and Gaussian Blur to handle those tasks.





We can also expand the study with adding some additional features. Notice that we can already analyze the age with deep learning. We can just blur the faces of non-adults for a different scenario. Besides, we can detect brand logos and blur them to hide some promotional ads. Background blurring can satisfy this duty as well.

I pushed the source code of this study to the GitHub. You can support this study if you star⭐️ the repo.


Like this blog? Support me on Patreon

Buy me a coffee


2 Comments

  1. Hey will you guide me on how to blur only specific targeted faces from a real-time video?

Comments are closed.