PiCamera2 with Flask Only Running Buffer/Camera once?

185 views Asked by At

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)
0

There are 0 answers