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()
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")
In [5]:
detectFaces("Photo2.jpg")