I am doing my final year project named as "Driver Drowsiness System" in which I am using haar-caascade and openCV. So after detection after driver is drowsy or yawny, there are two diffrent alarms which go-off and for that I have used Threading in Python. But after detecting yawn twice it shows ThreadException in 2nd Thread. Please help me.
Code :
#python drowniness_yawn.py --webcam webcam_index
from scipy.spatial import distance as dist
from imutils.video import VideoStream
from imutils import face_utils
from threading import Thread
import numpy as np
import argparse
import imutils
import time
import dlib
import cv2
import os
import os
import playsound as ps
from gtts import gTTS
def alarm(msg): # code for alarm
global alarm_status
global alarm_status2
global saying
language = 'en'
while alarm_status:
print('call')
s = msg+'"'
myobj = gTTS(text=s, lang=language, slow=False)
myobj.save("welcome.mp3")
# os.system("mpg321 welcome.mp3")
ps.playsound("welcome.mp3")
if alarm_status2:
print('call2')
saying = True
s = msg + '"'
# os.system(s)
myobj = gTTS(text=s, lang=language, slow=False)
myobj.save("welcome2.mp3")
try:
ps.playsound("welcome2.mp3")
except:
pass
saying = False
def eye_aspect_ratio(eye):
A = dist.euclidean(eye[1], eye[5])
B = dist.euclidean(eye[2], eye[4])
C = dist.euclidean(eye[0], eye[3])
ear = (A + B) / (2.0 * C)
return ear
def final_ear(shape):
(lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"]
(rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"]
leftEye = shape[lStart:lEnd]
rightEye = shape[rStart:rEnd]
leftEAR = eye_aspect_ratio(leftEye)
rightEAR = eye_aspect_ratio(rightEye)
ear = (leftEAR + rightEAR) / 2.0
return (ear, leftEye, rightEye)
def lip_distance(shape):
top_lip = shape[50:53]
top_lip = np.concatenate((top_lip, shape[61:64]))
low_lip = shape[56:59]
low_lip = np.concatenate((low_lip, shape[65:68]))
top_mean = np.mean(top_lip, axis=0)
low_mean = np.mean(low_lip, axis=0)
distance = abs(top_mean[1] - low_mean[1])
return distance
ap = argparse.ArgumentParser()
ap.add_argument("-w", "--webcam", type=int, default=0,
help="index of webcam on system")
args = vars(ap.parse_args())
EYE_AR_THRESH = 0.3
EYE_AR_CONSEC_FRAMES = 30
YAWN_THRESH = 20
alarm_status = False
alarm_status2 = False
saying = False
COUNTER = 0
print("-> Loading the predictor and detector...")
#detector = dlib.get_frontal_face_detector()
detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") #Faster but less accurate
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')
print("-> Starting Video Stream")
vs = VideoStream(src=args["webcam"]).start()
#vs= VideoStream(usePiCamera=True).start() //For Raspberry Pi
time.sleep(1.0)
while True:
frame = vs.read()
frame = imutils.resize(frame, width=450)
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#rects = detector(gray, 0)
rects = detector.detectMultiScale(gray, scaleFactor=1.1,
minNeighbors=5, minSize=(30, 30),
flags=cv2.CASCADE_SCALE_IMAGE)
#for rect in rects:
for (x, y, w, h) in rects:
rect = dlib.rectangle(int(x), int(y), int(x + w),int(y + h))
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
eye = final_ear(shape)
ear = eye[0]
leftEye = eye [1]
rightEye = eye[2]
distance = lip_distance(shape)
leftEyeHull = cv2.convexHull(leftEye)
rightEyeHull = cv2.convexHull(rightEye)
cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1)
cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1)
lip = shape[48:60]
cv2.drawContours(frame, [lip], -1, (0, 255, 0), 1)
if ear < EYE_AR_THRESH:
COUNTER += 1
if COUNTER >= EYE_AR_CONSEC_FRAMES:
if alarm_status == False:
alarm_status = True
t = Thread(target=alarm, args=('wake up sir',)) # Threading part for drowsiness alarm
t.deamon = True
t.start()
cv2.putText(frame, "DROWSINESS ALERT!", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
else:
COUNTER = 0
alarm_status = False
if (distance > YAWN_THRESH):
cv2.putText(frame, "Yawn Alert", (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
if alarm_status2 == False and saying == False:
alarm_status2 = True
t = Thread(target=alarm, args=('take some fresh air sir',)) # Threading part for yawn alarm
t.deamon = True
t.start()
else:
alarm_status2 = False
cv2.putText(frame, "EAR: {:.2f}".format(ear), (300, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(frame, "YAWN: {:.2f}".format(distance), (300, 60),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.imshow("Frame", frame)
key = cv2.waitKey(1) & 0xFF
if key == ord("q"):
break
cv2.destroyAllWindows()
vs.stop()
After executing it in console I get messsage which says:
> > python .\drowsiness_yawn.py
> -> Loading the predictor and detector...
> -> Starting Video Stream call2 call2 Exception in thread Thread-2 (alarm): Traceback (most recent call last): File
> "C:\Users\avdhu\anaconda3\envs\project\Lib\threading.py", line 1038,
> in _bootstrap_inner
> self.run() File "C:\Users\avdhu\anaconda3\envs\project\Lib\threading.py", line 975, in
> run
> self._target(*self._args, **self._kwargs) File "C:\Users\avdhu\OneDrive\Documents\Python
> Scripts\Drowsiness-and-Yawn-Detection-with-voice-alert-using-Dlib\drowsiness_yawn.py",
> line 39, in alarm
> myobj.save("welcome2.mp3") File "C:\Users\avdhu\anaconda3\envs\project\Lib\site-packages\gtts\tts.py",
> line 324, in save
> with open(str(savefile), "wb") as f:
> ^^^^^^^^^^^^^^^^^^^^^^^^^ PermissionError: [Errno 13] Permission denied: 'welcome2.mp3'
I get PermissionError for "welcome2.mp3" ,alarm responsible for yawn alarm.
Please help me