-
Notifications
You must be signed in to change notification settings - Fork 2
/
app.py
136 lines (125 loc) · 6.16 KB
/
app.py
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
from threading import Thread
import cv2
import pandas as pd
import playsound
from matplotlib import pyplot as plt
def sound_alarm(path):
# play an alarm sound
playsound.playsound(path)
def clip_color_avg(img):
# manually selected 10x10 square region of frame to monitor color variation
clip = img[213:223, 348:358, :]
h, w, c = clip.shape
avg_list = [[], [], []]
avg_channel = []
for i in range(h):
for j in range(w):
for c in range(3):
avg_list[c].append(clip[i, j, c])
avg_channel.append(sum(avg_list[0]) / len(avg_list[0]))
avg_channel.append(sum(avg_list[1]) / len(avg_list[1]))
avg_channel.append(sum(avg_list[2]) / len(avg_list[2]))
return avg_channel
# define two constants, one for the color change from initial value to indicate
# process completion and then a second constant for the number of consecutive
# frames the color must be below the threshold for to set off the
# alarm
COLOR_AR_THRESH = 60
COLOR_AR_CONSEC_FRAMES = 20
# initialize the frame counter as well as a boolean used to
# indicate if the alarm is going off
CONSECUTIVE_FRAME_COUNTER = 0
ALARM_ON = False
GIF_FRAMES = []
cap = cv2.VideoCapture('raw_media/titration.wmv')
if cap.isOpened():
Width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
Height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
FPS = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
print("Total # of frames {}".format(total_frames))
print("Width {}, Height {}".format(Width, Height))
ret1, img1 = cap.read()
if ret1:
START_AVG_CHANNEL_COLOR = clip_color_avg(img1)
print(
"Channel Colors Avg Value B:{}, G:{}, R:{}".format(START_AVG_CHANNEL_COLOR[0], START_AVG_CHANNEL_COLOR[1],
START_AVG_CHANNEL_COLOR[2]))
output = cv2.VideoWriter('output/titration_output.avi', fourcc, FPS, (int(Width), int(Height)), True)
number_frame = 1
raw_data = {'frames': [], 'avg_blue': [], 'avg_green': [], 'avg_red': []}
while True:
ret, img = cap.read()
if ret:
avg_channel = clip_color_avg(img)
if (abs(avg_channel[0] - START_AVG_CHANNEL_COLOR[0]) > COLOR_AR_THRESH) or (abs(
avg_channel[1] - START_AVG_CHANNEL_COLOR[1]) > COLOR_AR_THRESH) or (abs(
avg_channel[2] - START_AVG_CHANNEL_COLOR[2]) > COLOR_AR_THRESH):
CONSECUTIVE_FRAME_COUNTER += 1
if CONSECUTIVE_FRAME_COUNTER > COLOR_AR_CONSEC_FRAMES:
# if the alarm is not on, turn it on
if not ALARM_ON:
ALARM_ON = True
# check to see if an alarm file was supplied,
# and if so, start a thread to have the alarm
# sound played in the background
# if args["alarm"] != "":
t = Thread(target=sound_alarm,
args=('raw_media/alarm.wav',))
t.daemon = True
t.start()
# draw an alarm on the frame
cv2.putText(img, "PROCESS COMPLETE!", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
else:
CONSECUTIVE_FRAME_COUNTER = 0
ALARM_ON = False
# draw an alarm on the frame
cv2.putText(img, "PROCESS ONGOING", (50, 50),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1, cv2.LINE_AA)
raw_data['frames'].append(number_frame)
raw_data['avg_blue'].append(avg_channel[0])
raw_data['avg_green'].append(avg_channel[1])
raw_data['avg_red'].append(avg_channel[2])
cv2.putText(img, "Frame {}/{}".format(number_frame, total_frames),
(50, 300), cv2.FONT_HERSHEY_SIMPLEX, .5, (255, 255, 255), 1, cv2.LINE_AA)
cv2.putText(img, "SPARSHIK",
(50, 30), cv2.FONT_HERSHEY_SIMPLEX, .5, (255, 255, 255), 1, cv2.LINE_AA)
cv2.putText(img,
'B: {}'.format(int(raw_data['avg_blue'][number_frame - 1])), (550, 50),
cv2.FONT_HERSHEY_COMPLEX,
.5, (255, 0, 0), 1, cv2.LINE_AA)
cv2.putText(img, 'G: {}'.format(int(raw_data['avg_green'][number_frame - 1])), (550, 70),
cv2.FONT_HERSHEY_COMPLEX,
.5, (0, 255, 0), 1, cv2.LINE_AA)
cv2.putText(img,
'R: {}'.format(int(raw_data['avg_red'][number_frame - 1])), (550, 90),
cv2.FONT_HERSHEY_COMPLEX,
.5, (0, 0, 255), 1, cv2.LINE_AA)
cv2.rectangle(img=img, pt1=(348, 213), pt2=(358, 223),
color=(255, 255, 255), thickness=1)
number_frame += 1
cv2.imshow(winname='Titration Color Analysis', mat=img)
# save every 500 frame
if number_frame % 200 == 0:
output.write(img)
# Press Q on keyboard to exit
if cv2.waitKey(25) & 0xFF == ord('q'):
break
else:
break
df = pd.DataFrame(raw_data)
plt.suptitle('Titration Color Analysis', fontsize=14)
plt.plot('frames', 'avg_blue', data=df, color='blue', linewidth=2)
plt.plot('frames', 'avg_red', data=df, color='red', linewidth=2)
plt.plot('frames', 'avg_green', data=df, color='green', linewidth=2)
plt.xlabel(xlabel="Frame")
plt.ylabel(ylabel="Channel Values")
plt.savefig('output/titration.png')
df.to_csv('output/titration.csv')
# When everything done, release the video capture object
cap.release()
output.release()
# Closes all the frames
cv2.destroyAllWindows()