Skip to content

Commit e2f4d53

Browse files
committed
added video streaming detection by flask
1 parent 530664f commit e2f4d53

File tree

3 files changed

+104
-1
lines changed

3 files changed

+104
-1
lines changed

app.py

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from flask import Flask, request, render_template, flash, redirect, url_for, send_file
1+
from flask import Flask, request, render_template, flash, redirect, url_for, send_file, Response
22
from werkzeug.utils import secure_filename
33
from datetime import datetime
44
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
@@ -16,6 +16,37 @@
1616
net= cv2.dnn.readNet(prototxtPath, weightsPath)
1717
model= load_model('mask_detector.model')
1818

19+
def detect_and_predict_mask(frame,faceNet,maskModel):
20+
(h,w)= frame.shape[:2]
21+
blob= cv2.dnn.blobFromImage(frame,1.0,(300,300),(104.0,177.0,123.0))#normalization
22+
faceNet.setInput(blob)
23+
detections= faceNet.forward()
24+
25+
faces= []
26+
locs= []
27+
preds= []
28+
29+
for i in range(0,detections.shape[2]):
30+
confidence= detections[0,0,i,2]
31+
if confidence>0.5:
32+
box= detections[0,0,i,3:7]*np.array([w,h,w,h])
33+
(start_X,start_Y, end_X, end_Y)= box.astype('int')
34+
(start_X,start_Y)= (max(0,start_X),max(0,start_Y))
35+
(end_X,end_Y)= (min(w-1,end_X),min(h-1,end_Y))
36+
face= frame[start_Y:end_Y, start_X:end_X]
37+
face= cv2.cvtColor(face,cv2.COLOR_BGR2RGB)
38+
face= cv2.resize(face, (224,224))
39+
face= img_to_array(face)
40+
face= preprocess_input(face)
41+
faces.append(face)
42+
locs.append((start_X,start_Y,end_X,end_Y))
43+
44+
if len(faces)>0:
45+
faces = np.array(faces, dtype="float32")
46+
preds= maskModel.predict(faces)
47+
48+
return (locs,preds)
49+
1950
def allowed_file(filename):
2051
return '.' in filename and \
2152
filename.rsplit('.', 1)[1].lower() in ['png', 'jpg', 'jpeg']
@@ -80,5 +111,51 @@ def download(filename):
80111
# Returning file from appended path
81112
return send_file( os.path.join('static/online_detector_results',filename), as_attachment=True)
82113

114+
@app.route('/streaming')
115+
def streaming():
116+
return render_template('streaming.html')
117+
118+
119+
#video streaming
120+
121+
video = cv2.VideoCapture(0)
122+
123+
def gen_frames():
124+
while True:
125+
success, image = video.read()
126+
if not success:
127+
break
128+
else:
129+
(oheight, owidth) = image.shape[:2]
130+
adjusted_width = 400
131+
adjusted_height = int(adjusted_width * oheight / owidth)
132+
cv2.imshow("image", image)
133+
image = cv2.resize(image, (adjusted_width, adjusted_height), interpolation = cv2.INTER_AREA)
134+
(locs,preds)=detect_and_predict_mask(image,net,model)
135+
136+
for (loc,pred) in zip(locs,preds):
137+
(start_X,start_Y,end_X,end_Y)= loc
138+
(with_mask,without_mask)= pred
139+
if with_mask>without_mask:
140+
label="Mask"
141+
color= (0,255,0)
142+
else:
143+
label="No Mask"
144+
color= (0,0,255)
145+
146+
label="{}:{:.2f}%".format(label, max(with_mask,without_mask)*100)
147+
cv2.putText(image,label,(start_X,start_Y-10),cv2.FONT_HERSHEY_SIMPLEX,0.45,color,2)
148+
cv2.rectangle(image, (start_X,start_Y),(end_X,end_Y),color,2)
149+
150+
ret, jpeg = cv2.imencode('.jpg', image)
151+
frame = jpeg.tobytes()
152+
153+
yield (b'--frame\r\n'
154+
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
155+
156+
@app.route('/video_feed')
157+
def video_feed():
158+
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
159+
83160
if __name__ == '__main__':
84161
app.run(debug = True)

templates/homepage.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,8 @@ <h1 class="text-center bolded">Online Mask Detector</h1>
2525
<button onclick="location.href='{{ url_for('download', filename= outputImage) }}'" type="button"> Download </button>
2626
</div>
2727
{% endif %}
28+
<div style="text-align: center;">
29+
<button onclick="location.href='{{ url_for('streaming') }}'" type="button"> video streaming detection mode </button>
30+
</div>
2831
</body>
2932
</html>

templates/streaming.html

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<html lang="en">
2+
<head>
3+
<meta charset="UTF-8">
4+
<title>Mask Detection Online</title>
5+
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
6+
<link rel='stylesheet' href="{{ url_for('static',filename='css/style.css') }}">
7+
</head>
8+
<body>
9+
<h1 class="text-center bolded">Online Mask Detector</h1>
10+
<div class="container">
11+
<div class="row">
12+
<div class="col-lg-8 offset-lg-2">
13+
<h3 class="mt-5">Live Streaming</h3>
14+
<img src="{{ url_for('video_feed') }}" width="100%">
15+
</div>
16+
</div>
17+
</div>
18+
<div style="text-align: center;">
19+
<button onclick="location.href='{{ url_for('main_page') }}'" type="button"> image detection mode </button>
20+
</div>
21+
</body>
22+
</html>
23+

0 commit comments

Comments
 (0)