I am very confused why this app.py file is only making the picamera2 be accessed once? Probably explaining it bad, but the generate_frames() function only goes through the 20 buffers (set in the previous config), why does it not continue to run the camera like a stream? When i load the page, its realtime working but only for the 20 frames. here is the code.
#!/usr/bin/python3
from flask import Flask, render_template, Response
import cv2
import time
from picamera2 import Picamera2, MappedArray
app = Flask(__name__)
# Initialize the face detector
face_detector = cv2.CascadeClassifier("/var/www/fullfacescanner.xml")
# Initialize and configure the camera
picam2 = Picamera2()
config = picam2.create_preview_configuration(main={"size": (480, 480)},
lores={"size": (320, 240), "format": "YUV420"},
buffer_count=20, queue=False)
picam2.configure(config)
picam2.start(show_preview=False)
(w0, h0) = picam2.stream_configuration("main")["size"]
(w1, h1) = picam2.stream_configuration("lores")["size"]
s1 = picam2.stream_configuration("lores")["stride"]
def detect_faces(buffer):
print("Detecting face...")
grey = buffer[:s1 * h1].reshape((h1, s1))
return face_detector.detectMultiScale(grey, 1.1, 3)
def generate_frames():
while True:
try:
print("Generating a new frame...")
buffer = picam2.capture_buffer("lores")
detected_faces = detect_faces(buffer)
try:
with MappedArray(picam2.capture_request(), "main") as m:
print("face detected...")
for f in detected_faces:
(x, y, w, h) = [c * n // d for c, n, d in zip(f, (w0, h0) * 2, (w1, h1) * 2)]
cv2.rectangle(m.array, (x, y), (x + w, y + h), (0, 255, 0), 2)
_, buffer = cv2.imencode('.jpg', m.array)
frame = buffer.tobytes()
yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
except Exception as e:
print(f"An error occurred: {e}")
break
except Exception as e:
print(f"An error occurred: {e}")
break
@app.route('/')
def index():
# Main page of the web application
return render_template('index.html')
@app.route('/video_feed')
def video_feed():
# Video streaming route
return Response(generate_frames(),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8000, threaded=True)