Skip to content

Commit 6858ced

Browse files
authored
Add files via upload
1 parent a745cac commit 6858ced

14 files changed

+491
-0
lines changed

Course_Demo.mkv

18 MB
Binary file not shown.

Drowsy-Driver-Detection.pdf

369 KB
Binary file not shown.

Readme

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Steps to run the driver drowsiness detection project (CSE 547 Discrete Mathematics):
2+
3+
1) Run the run_extract_eyes.sh program to track the eyes for different videos(training data) and to store the patches of the eyes in a folder for every video. (Alert and Drowsy)
4+
2) Use this training data to retrain the CNN model(Inception V3 model).
5+
3) Run extract_features.py to extract the features from the second last layer of the CNN model which is a 2048-d vector and to create a sequence of frames as a single vector to be given as an input to the LSTM which is a part of Recurrent Neural Networks(RNN)
6+
4) Run data.py and models.py
7+
5) Finally run train.py to get the final predictions for the test sequence of data and the alarm will sound if the model predicts the sequence to be in a drowsy state.
8+

TensorBoard.png

101 KB
Loading

data.py

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import csv
2+
import csv
3+
import numpy as np
4+
import random
5+
import glob
6+
import os.path
7+
import sys
8+
import operator
9+
import threading
10+
from keras.utils import to_categorical
11+
12+
class Dataset():
13+
14+
def __init__(self, seq_length=26, class_limit=2, image_shape=(56, 24, 3)):
15+
self.seq_length = seq_length
16+
self.class_limit = class_limit
17+
self.sequence_path = os.path.join('data', 'sequences')
18+
# Get the data.
19+
self.data = self.get_data()
20+
# Get the classes.
21+
self.classes = self.get_classes()
22+
23+
def get_data(self):
24+
with open(os.path.join('data', 'data_file.csv'), 'r') as fin:
25+
reader = csv.reader(fin)
26+
data = list(reader)
27+
28+
return data
29+
30+
31+
def get_classes(self):
32+
classes = []
33+
for item in self.data:
34+
if item[1] not in classes:
35+
classes.append(item[1])
36+
37+
# Sort them.
38+
classes = sorted(classes)
39+
40+
# Return.
41+
if self.class_limit is not None:
42+
return classes[:self.class_limit]
43+
else:
44+
return classes
45+
46+
def get_class_one_hot(self, class_str):
47+
# Encode it first.
48+
label_encoded = self.classes.index(class_str)
49+
50+
# Now one-hot it.
51+
label_hot = to_categorical(label_encoded, len(self.classes))
52+
53+
assert len(label_hot) == len(self.classes)
54+
55+
return label_hot
56+
57+
def get_all_sequences_in_memory(self, train_test):
58+
59+
#train, test = self.split_train_test()
60+
#data = train if train_test == 'train' else test
61+
62+
print"Loading samples into memory for --> ",train_test
63+
64+
X, y = [], []
65+
66+
for videos in self.data:
67+
if(videos[0] == train_test):
68+
sequence = self.get_extracted_sequence(videos)
69+
if sequence is None:
70+
print("Can't find sequence. Did you generate them?")
71+
raise
72+
X.append(sequence)
73+
y.append(self.get_class_one_hot(videos[1]))
74+
75+
return np.array(X), np.array(y)
76+
77+
78+
def get_extracted_sequence(self,video):
79+
"""Get the saved extracted features."""
80+
filename = video[2]
81+
path = os.path.join(self.sequence_path, filename + '-' + str(26) + \
82+
'-' + 'features' + '.npy')
83+
if os.path.isfile(path):
84+
return np.load(path)
85+
else:
86+
return None

data.pyc

2.92 KB
Binary file not shown.

data_file.csv

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
training,Drowsy,Drowsy_Video1,26
2+
training,Drowsy,Drowsy_Video2,26
3+
training,Drowsy,Drowsy_Video3,26
4+
training,Drowsy,Drowsy_Video4,26
5+
training,Drowsy,Drowsy_Video5,26
6+
training,Drowsy,Drowsy_Video6,26
7+
training,Drowsy,Drowsy_Video7,26
8+
training,Drowsy,Drowsy_Video8,26
9+
training,Alert,Alert_Video1,26
10+
training,Alert,Alert_Video2,26
11+
training,Alert,Alert_Video3,26
12+
training,Alert,Alert_Video4,26
13+
training,Alert,Alert_Video5,26
14+
training,Alert,Alert_Video6,26
15+
training,Alert,Alert_Video7,26
16+
training,Alert,Alert_Video8,26
17+
testing,Alert,Test_Alert1,26
18+
testing,Drowsy,Test_Drowsy1,26
19+
testing,Alert,Test_Alert2,26

extract_features.py

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import numpy as np
2+
import os.path
3+
import csv
4+
import glob
5+
import tensorflow as tf
6+
import h5py as h5py
7+
from keras.preprocessing import image
8+
from keras.applications.inception_v3 import InceptionV3, preprocess_input
9+
from keras.models import Model, load_model
10+
11+
def extractor(image_path):
12+
13+
with open('/home/tejas/Desktop/Course-Project-CV/output_graph.pb', 'rb') as graph_file:
14+
graph_def = tf.GraphDef()
15+
graph_def.ParseFromString(graph_file.read())
16+
tf.import_graph_def(graph_def, name='')
17+
18+
with tf.Session() as sess:
19+
pooling_tensor = sess.graph.get_tensor_by_name('pool_3:0')
20+
image_data = tf.gfile.FastGFile(image_path, 'rb').read()
21+
pooling_features = sess.run(pooling_tensor, \
22+
{'DecodeJpeg/contents:0': image_data})
23+
pooling_features = pooling_features[0]
24+
25+
return pooling_features
26+
27+
def extract_features():
28+
with open('data/data_file.csv','r') as f:
29+
reader = csv.reader(f)
30+
for videos in reader:
31+
path = os.path.join('data', 'sequences', videos[2] + '-' + str(26) + \
32+
'-features.npy')
33+
34+
path_frames = os.path.join('data', videos[0], videos[1])
35+
filename = videos[2]
36+
frames = sorted(glob.glob(os.path.join(path_frames, filename + '/*jpg')))
37+
38+
sequence = []
39+
for image in frames:
40+
with tf.Graph().as_default():
41+
features = extractor(image)
42+
print 'Appending sequence of image:',image,' of the video:',videos
43+
44+
45+
46+
sequence.append(features)
47+
48+
np.save(path,sequence)
49+
print 'Sequences saved successfully'
50+
51+
extract_features()

eyedetection.py

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import os
2+
import sys
3+
import cv2
4+
import matplotlib.pyplot as plt
5+
import numpy as np
6+
7+
8+
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
9+
eye_cascade_left = cv2.CascadeClassifier('haarcascade_lefteye_2splits.xml')
10+
eye_cascade_right = cv2.CascadeClassifier('haarcascade_righteye_2splits.xml')
11+
def help_message():
12+
print("Usage: [Question_Number] [Input_Video] [Output_Directory]")
13+
print("[Question Number]")
14+
print("1 Camshift")
15+
print("[Input_Video]")
16+
print("Path to the input video")
17+
print("[Output_Directory]")
18+
print("Output directory")
19+
print("Example usages:")
20+
print(sys.argv[0] + " 1 " + "02-1.avi " + "./")
21+
22+
23+
def detect_one_face(im):
24+
gray=cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
25+
26+
faces = face_cascade.detectMultiScale(gray, 1.2, 3)
27+
if len(faces) == 0:
28+
return (0,0,0,0)
29+
return faces[0]
30+
31+
def hsv_histogram_for_window(frame, window):
32+
# set up the ROI for tracking
33+
c,r,w,h = window
34+
roi = frame[r:r+h, c:c+w]
35+
hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
36+
mask = cv2.inRange(hsv_roi, np.array((0., 60.,32.)), np.array((180.,255.,255.)))
37+
roi_hist = cv2.calcHist([hsv_roi],[0],mask,[180],[0,180])
38+
cv2.normalize(roi_hist,roi_hist,0,255,cv2.NORM_MINMAX)
39+
return roi_hist
40+
41+
42+
def resample(weights):
43+
n = len(weights)
44+
indices = []
45+
C = [0.] + [sum(weights[:i+1]) for i in range(n)]
46+
u0, j = np.random.random(), 0
47+
for u in [(u0+i)/n for i in range(n)]:
48+
while u > C[j]:
49+
j+=1
50+
indices.append(j-1)
51+
return indices
52+
53+
# Camshift
54+
55+
def skeleton_tracker1(v, file_name):
56+
# Open output file
57+
output_name = sys.argv[3] + file_name
58+
output = open(output_name,"w")
59+
60+
61+
frameCounter = 0
62+
# read first frame
63+
ret ,frame = v.read()
64+
if ret == False:
65+
return
66+
67+
68+
# detect face in first frame
69+
c,r,w,h = detect_one_face(frame)
70+
pt = (0,c+w/2,r+h/2)
71+
# Write track point for first frame
72+
output.write("%d,%d,%d\n" % pt) # Write as 0,pt_x,pt_y
73+
frameCounter = frameCounter + 1
74+
75+
# set the initial tracking window
76+
track_window = (c,r,w,h)
77+
78+
# calculate the HSV histogram in the window
79+
# NOTE: you do not need this in the Kalman, Particle or OF trackers
80+
roi_hist = hsv_histogram_for_window(frame, (c,r,w,h)) # this is provided for you
81+
count = 0
82+
term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
83+
while(1):
84+
ret ,frame = v.read() # read another frame
85+
if ret == False:
86+
break
87+
hsv = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
88+
dst = cv2.calcBackProject([hsv],[0],roi_hist,[0,180],1)
89+
ret, track_window = cv2.CamShift(dst, track_window, term_crit)
90+
x,y,w,h = track_window
91+
# write the result to the output file
92+
pt = (frameCounter,x+w/2,y+h/2)
93+
output.write("%d,%d,%d\n" % pt) # Write as frame_index,pt_x,pt_y
94+
cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)
95+
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
96+
roi_gray = gray[y:y+h, x:x+w]
97+
roi_color = frame[y:y+h, x:x+w]
98+
99+
eyes_left = eye_cascade_left.detectMultiScale(roi_gray)
100+
eyes_right = eye_cascade_right.detectMultiScale(roi_gray)
101+
for (ex1,ey1,ew1,eh1) in eyes_left:
102+
break
103+
for (ex,ey,ew,eh) in eyes_right:
104+
break
105+
106+
frame[ey+eh:ey, ex:ex1+ew1]
107+
cv2.rectangle(roi_color,(ex-5,ey-5),(ex+(ex1-ex)+ew1+5,ey+eh+5),(0,255,0),2)
108+
109+
croppedImg = roi_color[ey1:ey1+eh1, ex:ex1+ew1]
110+
if(croppedImg.shape[0]<=0 or croppedImg.shape[1]<=0):
111+
frameCounter = frameCounter + 1
112+
continue
113+
print croppedImg.shape
114+
cv2.imshow('img',frame)
115+
cv2.imshow('img1',croppedImg)
116+
output_name = "./"+sys.argv[4]+str(frameCounter)+".jpg"
117+
cv2.imwrite(output_name, croppedImg)
118+
k = cv2.waitKey(1) & 0xff
119+
if k == 27:
120+
break
121+
frameCounter = frameCounter + 1
122+
output.close()
123+
124+
125+
if __name__ == '__main__':
126+
question_number = -1
127+
128+
question_number = int(sys.argv[1])
129+
if (question_number > 4 or question_number < 1):
130+
print("Input parameters out of bound ...")
131+
sys.exit()
132+
133+
# read video file
134+
video = cv2.VideoCapture(sys.argv[2]);
135+
if (question_number == 1):
136+
skeleton_tracker1(video, "output_camshift.txt")
137+

models.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from keras.layers import Dense, Flatten, Dropout, ZeroPadding3D
2+
from keras.layers.recurrent import LSTM
3+
from keras.models import Sequential, load_model
4+
from keras.optimizers import Adam, RMSprop
5+
from keras.layers.wrappers import TimeDistributed
6+
from keras.layers.convolutional import (Conv2D, MaxPooling3D, Conv3D,
7+
MaxPooling2D)
8+
from collections import deque
9+
import sys
10+
11+
class ResearchModels():
12+
def __init__(self, nb_classes, model, seq_length,
13+
saved_model=None, features_length=2048):
14+
15+
# Set defaults.
16+
self.seq_length = seq_length
17+
self.load_model = load_model
18+
self.saved_model = saved_model
19+
self.nb_classes = nb_classes
20+
self.feature_queue = deque()
21+
22+
# Set the metrics. Only use top k if there's a need.
23+
metrics = ['accuracy']
24+
#if self.nb_classes >= 10:
25+
# metrics.append('top_k_categorical_accuracy')
26+
27+
# Get the appropriate model.
28+
print("Loading LSTM model.")
29+
self.input_shape = (seq_length, features_length)
30+
self.model = self.lstm()
31+
# Now compile the network.
32+
optimizer = Adam(lr=0.00005)
33+
self.model.compile(loss='categorical_crossentropy', optimizer=optimizer,
34+
metrics=metrics)
35+
36+
print(self.model.summary())
37+
38+
def lstm(self):
39+
"""Build a simple LSTM network. We pass the extracted features from
40+
our CNN to this model predomenently."""
41+
# Model.
42+
print self.input_shape
43+
model = Sequential()
44+
model.add(LSTM(2048, return_sequences=True,
45+
input_shape=self.input_shape,
46+
dropout=0.5))
47+
model.add(Flatten())
48+
model.add(Dense(1024, activation='relu'))
49+
model.add(Dense(512, activation='relu'))
50+
model.add(Dropout(0.5))
51+
model.add(Dense(self.nb_classes, activation='softmax'))
52+
53+
return model
54+
55+

models.pyc

2.2 KB
Binary file not shown.

output_labels.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
alert eyes
2+
drowsy eyes

0 commit comments

Comments
 (0)