Sunday, March 17, 2019

Face anonymizer with Python

Abstract

On this article, I’ll introduce how to anonymize human’s face and the code for that with Python.
Although I’m not 100% sure, when we compare with before, I think the face detection has been reaching certain level of accuracy. If the picture is not so complex, with some accuracy, the faces are detected. With this face detection, relatively easily, we can anonymize human’s face.




Motivation

The motivation for this is really personal. I have a blog to introduce Brazilian life to Japanese.(I’m Japanese and living in Brazil because of the marriage with a Brazilian.) On that blog, I frequently post pictures. But sometimes, unexpected face of a pedestrian comes to my picture because of my lack of skill of taking a photo. So, I need to anonymize the person or avoid using that picture.

Output

When we have this kind of image, which is from my github profile, by anonymizing, we can exchange the face part with a coconut.



Of course, it is not necessary at all to choose coconut. Anything is okay.

Environment

The environment is as followings.
  • macOS Mojave version 10.14.3
  • Python 3.7.0

Algorithm

This anonymization algorithm is very simple.
  1. detect face part coordinates
  2. resize the coconut image to the size of the face part
  3. exchange the face part with resized coconut image

How to use

The whole code is on my github repository.
https://github.com/marubontan/face_anonymizer_bot
By the following commands, you can install it.

git clone git@github.com:marubontan/face_anonymizer_bot.git
pip install -e face_anonymizer_bot

On the terminal, by the following command, you can make an anonymized output. The part of target/image/path should be the path of the image you want to anonymize.
The anonymized image will be written out on the current directory with the name, output.jpg.

face_anonymize target/image/path

Code

From the github’s code, I extracted the main part. Actually, the code is very simple. Because Python has nice library for face detection. By using that, just by one line, we can get the coordinates information of the face part. So, only thing we need to do is to resize the image and replace the face part with that image.

import copy  
from typing import Tuple  
  
import cv2  
import face_recognition  
import numpy as np
  
def resize_image(image: np.ndarray, coordinates: Tuple[int]) -> np.ndarray:  
    top, right, bottom, left = coordinates  
    resized_image = cv2.resize(image, dsize=(right - left, bottom - top), interpolation=cv2.INTER_CUBIC)  
    return np.asarray(resized_image)  
  
  
def replace_faces(image: np.ndarray, embedding_image: np.ndarray) -> np.ndarray:  
    face_locations = face_recognition.face_locations(image)  
    resized_embedding_images = [resize_image(embedding_image, coordinates) for coordinates in face_locations]  
  
    output_image = copy.deepcopy(image)  
    for coordinates, embedding_image in zip(face_locations, resized_embedding_images):  
        top, right, bottom, left = coordinates  
        output_image[top:bottom, left:right, :] = embedding_image  
  
    return output_image