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.
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
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 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
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.
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.
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.
Support this blog if you do like!
Hey will you guide me on how to blur only specific targeted faces from a real-time video?
Please go to deepface library. It can find faces and age-gender as well