Interview / functions /video.py
Rahulk2197's picture
Upload 15 files
eb9b1e7 verified
import numpy as np
from scipy.spatial import distance as dist
from imutils import face_utils
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
def euclidean_distance(point1, point2):
return np.linalg.norm(point1 - point2)
def eyebrow(landmarks,sizes):
eyebrow_dist=[]
for landmark,size in zip(landmarks,sizes):
if landmark is not None:
right_eyebrow_inner = landmark[21]
left_eyebrow_inner = landmark[22]
eyebrow_distance = euclidean_distance(right_eyebrow_inner, left_eyebrow_inner)
normalized_eyebrow_distance = eyebrow_distance / size[0]
else:
normalized_eyebrow_distance=None
eyebrow_dist.append(normalized_eyebrow_distance)
return eyebrow_dist
def eye_aspect_ratio(eye):
A = dist.euclidean(eye[1], eye[5]) # Vertical distance 1
B = dist.euclidean(eye[2], eye[4]) # Vertical distance 2
C = dist.euclidean(eye[0], eye[3]) # Horizontal distance
ear = (A + B) / (2.0 * C) # EAR formula
return ear
def euclidean_distance(p1, p2):
return np.linalg.norm(p1 - p2)
# Function to detect smiles based on mouth aspect ratio
def detect_smiles(landmarks_list, face_sizes, fps=30, consecutive_frames=2):
smile_ratios = [] # Store the smile ratios for plotting
smiles = []
smile_durations = [] # To store the duration of each smile
total_smiles = 0
smile_in_progress = False
smile_start_frame = None
avg_dynamic_threshold=[]
for frame_idx, (landmarks, face_size) in enumerate(zip(landmarks_list, face_sizes)):
if landmarks is not None:
# Use NumPy array indices for the relevant mouth landmarks
left_corner = np.array(landmarks[48])
right_corner = np.array(landmarks[54])
top_lip = np.array(landmarks[51])
bottom_lip = np.array(landmarks[57])
mouth_width = euclidean_distance(left_corner, right_corner)
mouth_height = euclidean_distance(top_lip, bottom_lip)
face_width, face_height = face_size # face_size is (width, height)
if face_width > 0 and face_height > 0:
normalized_mouth_width = mouth_width / face_width
normalized_mouth_height = mouth_height / face_height
else:
normalized_mouth_width = 0
normalized_mouth_height = 0
smile_ratios.append(normalized_mouth_width)
dynamic_threshold = 0.2 + (0.05 * face_width / 100)
avg_dynamic_threshold.append(dynamic_threshold)
# print(dynamic_threshold)
# Check if the smile meets the threshold
if (normalized_mouth_width > dynamic_threshold) and (normalized_mouth_height > 0.06):
smiles.append(True)
if not smile_in_progress:
smile_in_progress = True
smile_start_frame = frame_idx # Record the start of the smile
else:
smiles.append(False)
if smile_in_progress and (frame_idx - smile_start_frame >= consecutive_frames):
smile_in_progress = False
smile_end_frame = frame_idx
smile_duration = (smile_end_frame - smile_start_frame) / fps # Calculate smile duration
smile_durations.append(smile_duration)
total_smiles += 1 # Increment total smile count
else:
smiles.append(None)
try:
avg_thr=sum(avg_dynamic_threshold)/len(avg_dynamic_threshold)
except:
avg_thr=0
return smiles, smile_ratios, total_smiles, smile_durations,avg_thr
# Function to detect blinks based on the eye aspect ratio (EAR)
import numpy as np
# Function to detect blinks based on the eye aspect ratio (EAR)
def detect_blinks(landmarks_list, face_sizes, ear_threshold=0.24, consecutive_frames=2):
ear_ratios = [] # Store EAR for plotting
blinks = []
# Variables to monitor consecutive low EAR values
blink_count = 0
consec_low_ear = 0
for landmarks, face in zip(landmarks_list, face_sizes):
if landmarks is not None:
left_eye = landmarks[36:42] # Points 36-41 (inclusive) for the left eye
right_eye = landmarks[42:48]
def eye_aspect_ratio(eye):
A = euclidean_distance(eye[1], eye[5])
B = euclidean_distance(eye[2], eye[4])
C = euclidean_distance(eye[0], eye[3])
ear = (A + B) / (2.0 * C)
return ear
left_ear = eye_aspect_ratio(left_eye)
right_ear = eye_aspect_ratio(right_eye)
avg_ear = (left_ear + right_ear) / 2.0
ear_ratios.append(avg_ear)
if avg_ear < ear_threshold:
consec_low_ear += 1
else:
# If low EAR is detected for enough consecutive frames, count as a blink
if consec_low_ear >= consecutive_frames:
blink_count += 1
consec_low_ear = 0 # Reset the consecutive low EAR counter
else:
blinks.append(None)
return blink_count, ear_ratios
# Function to detect yawns based on the vertical distance between top and bottom lips
# Function to detect yawns based on the vertical distance between top and bottom lips
def detect_yawns(landmarks_list, face_sizes, fps=30, consecutive_frames=3):
yawn_ratios = [] # Store the yawn ratios for plotting
yawns = []
yawn_durations = [] # To store the duration of each yawn
total_yawns = 0
yawn_in_progress = False
yawn_start_frame = None
for frame_idx, (landmarks, face_size) in enumerate(zip(landmarks_list, face_sizes)):
if landmarks is not None:
top_lip = np.array(landmarks[51])
bottom_lip = np.array(landmarks[57])
mouth_height = euclidean_distance(top_lip, bottom_lip)
face_width, face_height = face_size # face_size is (width, height)
if face_height > 0:
normalized_mouth_height = mouth_height / face_height
else:
normalized_mouth_height = 0
yawn_ratios.append(normalized_mouth_height)
# Check if the yawn meets the threshold
if normalized_mouth_height > 0.24:
yawns.append(True)
if not yawn_in_progress:
yawn_in_progress = True
yawn_start_frame = frame_idx # Record the start of the yawn
else:
yawns.append(False)
if yawn_in_progress and (frame_idx - yawn_start_frame >= consecutive_frames):
yawn_in_progress = False
yawn_end_frame = frame_idx
yawn_duration = (yawn_end_frame - yawn_start_frame) / fps # Calculate yawn duration
yawn_durations.append(yawn_duration)
total_yawns += 1 # Increment total yawn count
else:
yawns.append(None)
return yawns, yawn_ratios, total_yawns, yawn_durations