In today's lab, we will learn how to connect a Pi Camera to your Raspberry Pi and learn how to control it to capture photos and stream video.
from flask import Flask, render_template, Response
app = Flask(__name__)
@app.route('/')
def index():
return render_template("index.html")
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
Design the page to your liking, but you will need to include an <img> tag with a source that will be updated dynamically.
import cv2
from imutils.video.pivideostream import PiVideoStream
import imutils
import time
class RPiCamera(object):
def __init__(self):
self.stream = PiVideoStream().start()
time.sleep(2.0)
def __del__(self):
self.stream.stop()
def get_frame(self):
frame = self.stream.read()
result, jpeg = cv2.imencode('.jpg', frame)
return jpeg.tobytes()
#the generator, a special type of function that yields, instead of returns.
def gen(camera):
while True:
frame = camera.get_frame()
# Each frame is set as a jpg content type. Frame data is in bytes.
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
Think of a flipbook animation. Each page is contains an illustration, similar to the one before and after it with a slight change. When the pages are flipped through quickly, it gives it the illusion of a moving animation. With livestreaming, the concept is the same. You are capturing a series of images through your camera and displaying them in rapid sequence. There are many ways to create a livestreaming app, but the method we will use will show you how to incorporate the Pi Camera with Flask to create a low latency playback, giving you a real time livestream.
Each frame is saved as an image and once they are played in order, quickly, you can get an animation. The latency is the amount of time between each frame. The higher the latency, the laggier your animation will be.
Generator functions are a special type of function that allow you to iterate over an object. It allows the user to get one piece of data in the object at a time.
Instead of a return statement, it uses the yield keyword and will return the values in that order. Once it hits the yield statement, the function will pause until the object is iterated through again using next();
# A simple generator function
def my_gen():
n = 1
print('This is printed first')
# Generator function contains yield statements
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
>>> # It returns an object but does not start execution immediately.
>>> a = my_gen()
>>> # We can iterate through the items using next().
>>> next(a)
This is printed first
1
>>> # Once the function yields, the function is paused and the control is transferred to the caller.
>>> # Local variables and theirs states are remembered between successive calls.
>>> next(a)
This is printed second
2
>>> next(a)
This is printed at last
3
>>> # Finally, when the function terminates, StopIteration is raised automatically on further calls.
>>> next(a)
Traceback (most recent call last):
...
StopIteration
>>> next(a)
Traceback (most recent call last):
...
StopIteration
Resources:
Review Miguel Grinberg’s tutorial on Video Streaming with Flask.