2020-05-23 11:56:57 +02:00
|
|
|
from flask import Response
|
|
|
|
from flask import Flask
|
|
|
|
from flask import render_template
|
|
|
|
import threading
|
|
|
|
import argparse
|
|
|
|
import datetime
|
|
|
|
import time
|
|
|
|
import cv2
|
2020-05-24 11:08:14 +02:00
|
|
|
from hashlib import md5
|
2020-05-23 11:56:57 +02:00
|
|
|
|
|
|
|
outputFrame = None
|
|
|
|
lock = threading.Lock()
|
|
|
|
|
|
|
|
# initialize a flask object
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
cap = cv2.VideoCapture(0)
|
2020-05-24 11:08:14 +02:00
|
|
|
cap.set(cv2.CAP_PROP_FPS, 10)
|
2020-05-23 11:56:57 +02:00
|
|
|
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
|
|
|
|
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
|
|
|
|
|
2020-05-24 11:08:14 +02:00
|
|
|
fps = cap.get(cv2.CAP_PROP_FPS)
|
|
|
|
print("Frames per second using video.get(cv2.CAP_PROP_FPS) : {0}".format(fps))
|
|
|
|
|
2020-05-23 11:56:57 +02:00
|
|
|
time.sleep(1.0)
|
|
|
|
|
|
|
|
@app.route("/")
|
|
|
|
def index():
|
2020-06-04 13:50:01 +02:00
|
|
|
# return the rendered template
|
|
|
|
return render_template("index.html")
|
2020-05-23 11:56:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
def detect_motion(frameCount):
|
2020-06-04 13:50:01 +02:00
|
|
|
global vs, outputFrame, lock
|
|
|
|
lastframe = None
|
|
|
|
while True:
|
|
|
|
flag, frame = cap.read()
|
|
|
|
framedig = md5(frame).digest()
|
2020-05-24 11:08:14 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
if lastframe == framedig:
|
|
|
|
print("Duplicate frame, skipping")
|
|
|
|
continue
|
2020-05-23 11:56:57 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
if not flag:
|
|
|
|
continue
|
|
|
|
lastframe = framedig
|
2020-05-23 11:56:57 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
timestamp = datetime.datetime.now()
|
|
|
|
cv2.putText(frame, timestamp.strftime(
|
|
|
|
"%A %d %B %Y %I:%M:%S%p"), (10, 15),
|
|
|
|
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1)
|
|
|
|
|
|
|
|
with lock:
|
|
|
|
outputFrame = frame.copy()
|
2020-05-23 11:56:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
def generate():
|
2020-06-04 13:50:01 +02:00
|
|
|
global outputFrame, lock
|
|
|
|
while True:
|
|
|
|
with lock:
|
|
|
|
if outputFrame is None:
|
|
|
|
continue
|
2020-05-23 11:56:57 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
(flag, encodedImage) = cv2.imencode(".jpg", outputFrame)
|
|
|
|
# ensure the frame was successfully encoded
|
|
|
|
if not flag:
|
|
|
|
continue
|
2020-05-23 11:56:57 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
# yield the output frame in the byte format
|
|
|
|
yield(b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
|
|
|
|
bytearray(encodedImage) + b'\r\n')
|
2020-05-23 11:56:57 +02:00
|
|
|
|
2020-06-04 13:50:01 +02:00
|
|
|
time.sleep(0.2)
|
2020-05-24 11:08:14 +02:00
|
|
|
|
2020-05-23 11:56:57 +02:00
|
|
|
|
|
|
|
@app.route("/video_feed")
|
|
|
|
def video_feed():
|
2020-06-04 13:50:01 +02:00
|
|
|
# return the response generated along with the specific media
|
|
|
|
# type (mime type)
|
|
|
|
return Response(generate(),
|
|
|
|
mimetype = "multipart/x-mixed-replace; boundary=frame")
|
2020-05-23 11:56:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
# check to see if this is the main thread of execution
|
|
|
|
if __name__ == '__main__':
|
2020-06-04 13:50:01 +02:00
|
|
|
# construct the argument parser and parse command line arguments
|
|
|
|
ap = argparse.ArgumentParser()
|
|
|
|
ap.add_argument("-i", "--ip", type=str, required=True,
|
|
|
|
help="ip address of the device")
|
|
|
|
ap.add_argument("-o", "--port", type=int, required=True,
|
|
|
|
help="ephemeral port number of the server (1024 to 65535)")
|
|
|
|
ap.add_argument("-f", "--frame-count", type=int, default=32,
|
|
|
|
help="# of frames used to construct the background model")
|
|
|
|
args = vars(ap.parse_args())
|
|
|
|
# start a thread that will perform motion detection
|
|
|
|
t = threading.Thread(target=detect_motion, args=(
|
|
|
|
args["frame_count"],))
|
|
|
|
t.daemon = True
|
|
|
|
t.start()
|
|
|
|
# start the flask app
|
|
|
|
app.run(host=args["ip"], port=args["port"], debug=True,
|
|
|
|
threaded=True, use_reloader=False)
|