Spaces:
Sleeping
Sleeping
File size: 7,541 Bytes
ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 ee94b36 eb9b1e7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
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
|