Adding Objects To Faces¶

Import Libraries¶

In [1]:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

The Object of Choice¶

In [2]:
img = cv.imread('hat.jpg')
plt.imshow(img)
plt.axis('off')
plt.show()
No description has been provided for this image

Function to Place Hat on Head¶

The imported hat hasn't got an alpha channel, so all the white pixels were made transparent

The code is modified from an earlier file.

In [3]:
def detectFaces(img_path):
    img = cv.imread(img_path)
    img = cv.resize(img, (400, 300))
    img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)

    face_cascade = cv.CascadeClassifier(cv.data.haarcascades + 'haarcascade_frontalface_default.xml')
    faces = face_cascade.detectMultiScale(img_rgb, scaleFactor=1.05, minNeighbors=7, minSize=(20, 20))

    num_faces = 0
    hat_img = cv.imread("hat.jpg", cv.IMREAD_UNCHANGED)  # Load hat image with alpha channel

    # Convert hat image to RGBA if it doesn't have an alpha channel
    if hat_img.shape[2] == 3:
        b_channel, g_channel, r_channel = cv.split(hat_img)
        alpha_channel = np.ones_like(b_channel) * 255  # Create an alpha channel with all pixels set to 255 (fully opaque)
        hat_img = cv.merge((b_channel, g_channel, r_channel, alpha_channel))

    # Make white pixels in the hat image transparent
    white_pixels = np.all(hat_img[:, :, :3] == [255, 255, 255], axis=-1)
    hat_img[white_pixels] = [0, 0, 0, 0]  # Set the alpha channel of white pixels to 0 (fully transparent)

    for (x, y, w, h) in faces:
        # Resize hat image to fit face width and adjust position
        hat_resized = cv.resize(hat_img, (int(w*1.1), int(0.8*h)))
        x_offset = x
        y_offset = int(y - 0.75*h)
        
        # Place hat on the face
        for c in range(0, 3):
            img_rgb[y_offset:y_offset+hat_resized.shape[0], x_offset:x_offset+hat_resized.shape[1], c] = \
                hat_resized[:, :, c] * (hat_resized[:, :, 3]/255.0) + img_rgb[y_offset:y_offset+hat_resized.shape[0], x_offset:x_offset+hat_resized.shape[1], c] * (1.0 - hat_resized[:, :, 3]/255.0)
        
        num_faces += 1
    
    plt.imshow(img_rgb)
    plt.axis('off')
    plt.show()
In [4]:
detectFaces("Photo1.jpg")
No description has been provided for this image
In [5]:
detectFaces("Photo2.jpg")
No description has been provided for this image