Reputation: 1
The following python script runs on a Pi zero with camera. If I connect from a client with webbrowser the "while True" loop in the streaminhandler prints a message when motion is detected.
I don't always connect from a client but I want the loop started (as if a client connects) upon booting the Pi which starts the script.
How can I make the http server "connect to itself"? I tried the "request" line in the "try" block but that doesn't work, it never gets executed.
#!/usr/bin/python
import cv2
import http.server
import socketserver
import requests
import time
import subprocess
def camera():
camera = cv2.VideoCapture("/dev/video0")
if not camera.isOpened():
print("Cannot open camera.")
raise SystemExit
camera.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
camera.set(cv2.CAP_PROP_FPS, 15)
return camera
def process(frame1, frame2):
framediff = cv2.absdiff(frame1, frame2)
framegray = cv2.cvtColor(framediff,cv2.COLOR_BGR2GRAY)
frameblur = cv2.GaussianBlur(framegray,(5,5),0)
threshold = cv2.threshold(frameblur,20,255,cv2.THRESH_BINARY)[1]
dilated = cv2.dilate(threshold,None,iterations=10)
contours = cv2.findContours(dilated,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)[0]
motion = False
for contour in contours:
if cv2.contourArea(contour) < 10000:
continue
(x, y, w, h) = cv2.boundingRect(contour)
cv2.rectangle(frame2,(x, y),(x+w, y+h),(0,255,0),2)
motion = True
return frame2, motion
#return cv2.flip(frame2, -1)
def webpage():
return """<html><body>
<img src="stream.mjpg" width="640" height="480" />
</body></html>"""
class streaminghandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path == "/index.html":
content = webpage().encode("utf-8")
self.send_response(200)
self.send_header("Content-Type", "text/html")
self.send_header("Content-Length", len(content))
self.end_headers()
self.wfile.write(content)
elif self.path == "/stream.mjpg":
self.send_response(200)
self.send_header("Content-type", "multipart/x-mixed-replace; boundary=--jpgboundary")
self.end_headers()
while True:
frame1 = camera.read()[1]
frame2 = camera.read()[1]
frame, motion = process(frame1, frame2)
if motion:
print("Motion detected.. " + time.asctime( time.localtime(time.time())))
frame = cv2.imencode(".jpg", frame)[1]
time.sleep(frameinterval)
self.send_header("Content-type", "image/jpeg")
self.send_header("Content-length", len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b"\r\n--jpgboundary\r\n")
elif self.path == "/image.jpg":
self.send_response(200)
self.send_header("Content-type", "multipart/x-mixed-replace; boundary=--jpgboundary")
self.end_headers
frame1 = camera.read()[1]
frame2 = camera.read()[1]
frame, motion = process(frame1, frame2)
frame = cv2.imencode(".jpg", frame)[1]
self.send_header("Content-type", "image/jpeg")
self.send_header("Content-length", len(frame))
self.end_headers()
self.wfile.write(frame)
self.wfile.write(b"\r\n--jpgboundary\r\n")
class streamingserver(socketserver.ThreadingMixIn, http.server.HTTPServer):
"""Handle requests in a separate thread."""
try:
camera = camera()
frameinterval = 1 / camera.get(cv2.CAP_PROP_FPS)
streaming_server = streamingserver(("", 8000), streaminghandler)
print("server started at port 8000")
streaming_server.serve_forever()
r = requests.get("http://localhost:8000/stream.mjpg")
except Exception as error:
print(error)
finally:
streaming_server.socket.close()
camera.release()
Upvotes: 0
Views: 555