I have implemented the code where i am capturing the image and saving that image, After that i have another code which adds jewelry to that captured image, But i am facing issue while adding jewelry to captured face error==> "face_landmarks = face_landmarks_list[0]
IndexError: list index out of range"
Can some one help me with the solutions.
image capturing code
import cv2
cam = cv2.VideoCapture(0)
cv2.namedWindow("test")
img_counter = 0
while True:
ret, frame = cam.read()
if not ret:
print("failed to grab frame")
break
cv2.imshow("test", frame)
k = cv2.waitKey(1)
if k%256 == 27:
# ESC pressed
print("Escape hit, closing...")
break
elif k%256 == 32:
# SPACE pressed
img_name = "opencv_frame_{}.png".format(img_counter)
cv2.imwrite(img_name, frame)
print("{} written!".format(img_name))
img_counter += 1
cam.release()
cv2.destroyAllWindows()
-------- below code for adding image -------- import cv2 import face_recognition from PIL import Image, ImageDraw import numpy
jewel_img = cv2.imread("jewelery.png")
frame = cv2.imread('akash.jpg')
frame = cv2.resize(frame, (432, 576))
# Returns a list of face landmarks present on frame
face_landmarks_list = face_recognition.face_landmarks(frame)
# For demo images only one person is present in image
face_landmarks = face_landmarks_list[0]
shape_chin = face_landmarks['chin']
# x, y cordinates on frame where jewelery will be added
x = shape_chin[3][0]
y = shape_chin[6][1]
# Jewelry width & height calculated using face chin cordinates
img_width = abs(shape_chin[3][0] - shape_chin[14][0])
img_height = int(1.02 * img_width)
jewel_img = cv2.resize(jewel_img, (img_width, img_height), interpolation = cv2.INTER_AREA)
jewel_gray = cv2.cvtColor(jewel_img, cv2.COLOR_BGR2GRAY)
# All pixels greater than 230 will be converted to white and others will be converted to black
thresh, jewel_mask = cv2.threshold(jewel_gray, 230, 255, cv2.THRESH_BINARY)
# Convert to black the background of jewelry image
jewel_img[jewel_mask == 255] = 0
# Crop out jewelry area from original frame
jewel_area = frame[y: y + img_height, x: x + img_width]
# bitwise_and will convert all black regions in any image to black in resulting image
masked_jewel_area = cv2.bitwise_and(jewel_area, jewel_area, mask = jewel_mask)
# add both images so that the black region in any image will result in another image non black regions being rendered over that area
final_jewel = cv2.add(masked_jewel_area, jewel_img)
# replace original frame jewel area with newly created jewel_area
frame[y: y + img_height, x: x + img_width] = final_jewel
# convert image to RGB format to read it in pillow library
rgb_img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pil_img = Image.fromarray(rgb_img)
draw = ImageDraw.Draw(pil_img, 'RGBA')
draw.polygon(face_landmarks['left_eyebrow'], fill = (23, 26, 31, 100))
draw.polygon(face_landmarks['right_eyebrow'], fill = (23, 26, 31, 100))
draw.polygon(face_landmarks['top_lip'], fill = (158, 63, 136, 100))
draw.polygon(face_landmarks['bottom_lip'], fill = (158, 63, 136, 100))
draw.polygon(face_landmarks['left_eye'], fill = (23, 26, 31, 100))
draw.polygon(face_landmarks['right_eye'], fill = (23, 26, 31, 100))
# calculate x, y, radius
for ellipse to be drawn between two eyebrows
x_centre_eyebrow = face_landmarks['nose_bridge'][0][0]
y_centre_eyebrow = face_landmarks['left_eyebrow'][4][1]
r = int(1 / 4 * abs(face_landmarks['left_eyebrow'][4][0] - face_landmarks['right_eyebrow'][0][0]))
draw.ellipse((x_centre_eyebrow - r, y_centre_eyebrow - r, x_centre_eyebrow + r, y_centre_eyebrow + r), fill = (128, 0, 128, 100))
pil_img.show()
Error says the answer
face_landmarks = face_landmarks_list[0]
You need to check whether a single face is detected or not.
Your second code, should start by checking the stored list length.
If the length is greater than 0, meaning some faces are detected, then continue.
# Returns a list of face landmarks present on frame
face_landmarks_list = face_recognition.face_landmarks(frame)
if len(face_landmarks_list) > 0:
jewel_img = cv2.imread("jewelery.png")
frame = cv2.imread('akash.jpg')
frame = cv2.resize(frame, (432, 576))
# For demo images only one person is present in image
face_landmarks = face_landmarks_list[0]