11# Libraries
2+ import os
23import cv2
34import dlib
45import json
78import tkinter
89import datetime
910
11+ # Variables
12+ DEBUG_MODE = False
13+ MAX_TRACKERS = 50
14+ BASE_DIR = os .path .dirname (__file__ )
15+
1016# Functions
1117def show_plot_image_data (input : list ):
12- l1 = []
13- l2 = []
14- stick = []
15- for time , totgreen , totred in input :
16- stick .append (time )
17- l1 .append (totgreen )
18- l2 .append (totred )
19- figure = plot .figure ()
20- figure .canvas .manager .window .title ('Recent' )
21- figure .canvas .manager .window .iconphoto (False , tkinter .PhotoImage (file = ' learning_focus.png' ))
22- plot .title ('Recent' )
23- plot .bar (numpy .arange (len (l1 )), l1 , width = 0.4 , color = 'green' , label = 'Good' )
24- for x , y in enumerate (l1 ):
25- plot .text (x , y , y )
26- plot .bar (numpy .arange (len (l2 )) + 0.4 , l2 , width = 0.4 , color = 'red' , label = 'Bad' )
27- for x , y in enumerate (l2 ):
28- plot .text (x + 0.4 , y , y )
29- plot .xticks (numpy .arange (len (input )) + 0.4 / 2 , stick )
30- plot .ylabel ('Time (Minute)' )
31- plot .legend (loc = 'upper left' )
32- plot .show ()
18+ l1 = []
19+ l2 = []
20+ stick = []
21+ for time , totgreen , totred in input :
22+ stick .append (time )
23+ l1 .append (totgreen )
24+ l2 .append (totred )
25+ figure = plot .figure ()
26+ figure .canvas .manager .window .title ('Recent' )
27+ figure .canvas .manager .window .iconphoto (False , tkinter .PhotoImage (file = os . path . join ( BASE_DIR , './ learning_focus.png') ))
28+ plot .title ('Recent' )
29+ plot .bar (numpy .arange (len (l1 )), l1 , width = 0.4 , color = 'green' , label = 'Good' )
30+ for x , y in enumerate (l1 ):
31+ plot .text (x , y , y )
32+ plot .bar (numpy .arange (len (l2 )) + 0.4 , l2 , width = 0.4 , color = 'red' , label = 'Bad' )
33+ for x , y in enumerate (l2 ):
34+ plot .text (x + 0.4 , y , y )
35+ plot .xticks (numpy .arange (len (input )) + 0.4 / 2 , stick )
36+ plot .ylabel ('Time (Minute)' )
37+ plot .legend (loc = 'upper left' )
38+ plot .show ()
3339
3440def save_total_time_data (time : str , totgreen : float , totred : float ):
35- try :
36- with open ('./recent.json' , 'r' , encoding = 'utf-8' ) as f :
37- input = json .load (f )
38- except (FileNotFoundError , json .decoder .JSONDecodeError ):
39- input = []
40- with open ('./recent.json' , 'w' , encoding = 'utf-8' ) as f :
41- input .append ([time , totgreen , totred ])
42- input = input [- 3 :]
43- show_plot_image_data (input )
44- json .dump (input , f )
41+ try :
42+ with open (os . path . join ( BASE_DIR , './recent.json' ) , 'r' , encoding = 'utf-8' ) as f :
43+ input = json .load (f )
44+ except (FileNotFoundError , json .decoder .JSONDecodeError ):
45+ input = []
46+ with open (os . path . join ( BASE_DIR , './recent.json' ) , 'w' , encoding = 'utf-8' ) as f :
47+ input .append ([time , totgreen , totred ])
48+ input = input [- 3 :]
49+ show_plot_image_data (input )
50+ json .dump (input , f )
4551
4652def main ():
47- cap = cv2 .VideoCapture (0 )
48- time .sleep (1 )
49- detector = dlib .get_frontal_face_detector ()
50- predictor = dlib .shape_predictor ('learning_focus.dat' )
51- trackers = [dlib .correlation_tracker () for _ in range (10 )]
52- status = 'green'
53- totgreen = 0
54- totred = 0
55- while True :
56- timestampstart = time .time ()
57- frame = cap .read ()[1 ]
58- gray = cv2 .cvtColor (src = frame , code = cv2 .COLOR_BGR2GRAY )
59- faces = detector (gray )
60- for k in range (len (faces )):
61- trackers [k ].start_track (frame , faces [k ])
62- trackers [k ].update (frame )
63- pos = trackers [k ].get_position ()
64- cv2 .rectangle (frame , (int (pos .left () - 20 ), int (pos .top () - 20 )), (int (pos .right () + 20 ), int (pos .bottom () + 20 )), ((0 , 0 , 255 ) if status == 'red' else (0 , 255 , 0 )), 2 )
65- if len (faces ) == 0 :
66- status = 'red'
67- else :
68- status = 'green'
69- for face in faces :
70- landmarks = predictor (image = gray , box = face )
71- if 1.5 * (landmarks .part (37 ).y - landmarks .part (19 ).y ) < (landmarks .part (8 ).y - landmarks .part (57 ).y ):
72- try :
73- b , g , r = frame [int (landmarks .part (40 ).x - 1 ), int (landmarks .part (40 ).y - 3 )]
74- except IndexError :
75- status = 'red'
76- break
77- if 0.11 * b + 0.59 * g + 0.3 * r >= 130 :
78- status = 'red'
79- break
80- if 2 * (landmarks .part (29 ).x - landmarks .part (1 ).x ) < (landmarks .part (15 ).x - landmarks .part (29 ).x ):
81- try :
82- b , g , r = frame [int (landmarks .part (42 ).x + 6 ), int (landmarks .part (42 ).y - 3 )]
83- except IndexError :
84- status = 'red'
85- break
86- if 0.11 * b + 0.59 * g + 0.3 * r >= 100 :
87- status = 'red'
88- break
89- if (landmarks .part (29 ).x - landmarks .part (1 ).x ) > (2 * (landmarks .part (15 ).x - landmarks .part (29 ).x )):
90- try :
91- b , g , r = frame [int (landmarks .part (42 ).x + 4 ), int (landmarks .part (39 ).y - 3 )]
92- except IndexError :
93- status = 'red'
94- break
95- if 0.11 * b + 0.59 * g + 0.3 * r <= 100 :
96- status = 'red'
97- break
98- try :
99- if (landmarks .part (40 ).y - landmarks .part (38 ).y > 10 ) and (landmarks .part (46 ).y - landmarks .part (44 ).y < 10 ):
100- status = 'red'
101- break
102- except IndexError :
103- status = 'red'
104- break
105- for n in range (68 ):
106- x = landmarks .part (n ).x
107- y = landmarks .part (n ).y
108- cv2 .circle (img = frame , center = (x , y ), radius = 2 , color = (255 , 255 , 255 ), thickness = - 1 )
109- if status == 'green' :
110- totgreen += time .time () - timestampstart
111- else :
112- totred += time .time () - timestampstart
113- cv2 .imshow (winname = 'Face' , mat = frame )
114- if 0xFF & cv2 .waitKey (1 ) == 27 :
115- break
116- cap .release ()
117- cv2 .destroyAllWindows ()
118- print ('Total good studying time (Minute): ' + str (round (totgreen / 60 , 2 )))
119- print ('Total bad studying time (Minute): ' + str (round (totred / 60 , 2 )))
120- save_total_time_data ('{:04}-{:02}-{:02} {:02}:{:02}:{:02}' .format (datetime .datetime .now ().year , datetime .datetime .now ().month , datetime .datetime .now ().day , datetime .datetime .now ().hour , datetime .datetime .now ().minute , datetime .datetime .now ().second ), round (totgreen / 60 , 2 ), round (totred / 60 , 2 ))
53+ cap = cv2 .VideoCapture (0 )
54+ time .sleep (1 )
55+ detector = dlib .get_frontal_face_detector ()
56+ predictor = dlib .shape_predictor (os .path .join (BASE_DIR , './learning_focus.dat' ))
57+ trackers = [dlib .correlation_tracker () for _ in range (MAX_TRACKERS )]
58+ status = 'green'
59+ totgreen = 0
60+ totred = 0
61+ while True :
62+ timestampstart = time .time ()
63+ frame = cap .read ()[1 ]
64+ gray = cv2 .cvtColor (src = frame , code = cv2 .COLOR_BGR2GRAY )
65+ faces = detector (gray )
66+ for k in range (len (faces )):
67+ trackers [k ].start_track (frame , faces [k ])
68+ trackers [k ].update (frame )
69+ pos = trackers [k ].get_position ()
70+ cv2 .rectangle (frame , (int (pos .left () - 20 ), int (pos .top () - 20 )), (int (pos .right () + 20 ), int (pos .bottom () + 20 )), ((0 , 0 , 255 ) if status == 'red' else (0 , 255 , 0 )), 2 )
71+ if len (faces ) == 0 :
72+ status = 'red'
73+ else :
74+ status = 'green'
75+ for face in faces :
76+ landmarks = predictor (image = gray , box = face )
77+ if 1.5 * (landmarks .part (37 ).y - landmarks .part (19 ).y ) < (landmarks .part (8 ).y - landmarks .part (57 ).y ):
78+ try :
79+ b , g , r = frame [int (landmarks .part (40 ).x - 1 ), int (landmarks .part (40 ).y - 3 )]
80+ except IndexError :
81+ status = 'red'
82+ break
83+ if 0.11 * b + 0.59 * g + 0.3 * r >= 130 :
84+ status = 'red'
85+ break
86+ if 2 * (landmarks .part (29 ).x - landmarks .part (1 ).x ) < (landmarks .part (15 ).x - landmarks .part (29 ).x ):
87+ try :
88+ b , g , r = frame [int (landmarks .part (42 ).x + 6 ), int (landmarks .part (42 ).y - 3 )]
89+ except IndexError :
90+ status = 'red'
91+ break
92+ if 0.11 * b + 0.59 * g + 0.3 * r >= 100 :
93+ status = 'red'
94+ break
95+ if (landmarks .part (29 ).x - landmarks .part (1 ).x ) > (2 * (landmarks .part (15 ).x - landmarks .part (29 ).x )):
96+ try :
97+ b , g , r = frame [int (landmarks .part (42 ).x + 4 ), int (landmarks .part (39 ).y - 3 )]
98+ except IndexError :
99+ status = 'red'
100+ break
101+ if 0.11 * b + 0.59 * g + 0.3 * r <= 100 :
102+ status = 'red'
103+ break
104+ try :
105+ if (landmarks .part (40 ).y - landmarks .part (38 ).y > 10 ) and (landmarks .part (46 ).y - landmarks .part (44 ).y < 10 ):
106+ status = 'red'
107+ break
108+ except IndexError :
109+ status = 'red'
110+ break
111+ if DEBUG_MODE == True :
112+ for n in range (68 ):
113+ x = landmarks .part (n ).x
114+ y = landmarks .part (n ).y
115+ cv2 .circle (img = frame , center = (x , y ), radius = 2 , color = (255 , 255 , 255 ), thickness = - 1 )
116+ if status == 'green' :
117+ totgreen += time .time () - timestampstart
118+ else :
119+ totred += time .time () - timestampstart
120+ cv2 .imshow (winname = 'Face' , mat = cv2 .flip (frame , 1 ))
121+ if 0xFF & cv2 .waitKey (1 ) == 27 :
122+ break
123+ cap .release ()
124+ cv2 .destroyAllWindows ()
125+ print ('Total good studying time (Minute): ' + str (round (totgreen / 60 , 2 )))
126+ print ('Total bad studying time (Minute): ' + str (round (totred / 60 , 2 )))
127+ save_total_time_data ('{:04}-{:02}-{:02} {:02}:{:02}:{:02}' .format (datetime .datetime .now ().year , datetime .datetime .now ().month , datetime .datetime .now ().day , datetime .datetime .now ().hour , datetime .datetime .now ().minute , datetime .datetime .now ().second ), round (totgreen / 60 , 2 ), round (totred / 60 , 2 ))
121128
122129# Main
123130if __name__ == '__main__' :
124- from matplotlib import use as usebackend
125- usebackend ('TkAgg' )
126- from matplotlib import pyplot as plot
127- main ()
131+ from matplotlib import use as usebackend
132+ usebackend ('TkAgg' )
133+ from matplotlib import pyplot as plot
134+ main ()
0 commit comments