How to stream opencv frame with django frame in realtime?

luvwinnie picture luvwinnie · Aug 27, 2017 · Viewed 6.9k times · Source

I'm trying to use raspberry pi capture the image from USB camera and stream it with Django framework I have tried to use StreamingHttpResponse to stream the frame from Opencv2. However, it just shows 1 frame and not replacing the image.

How can I replace the image in real time?

Here is my code.

from django.shortcuts import render
from django.http import HttpResponse,StreamingHttpResponse
import cv2
import time

class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture(0)
    def __del__(self):
        self.video.release()

    def get_frame(self):
        ret,image = self.video.read()
        ret,jpeg = cv2.imencode('.jpg',image)
        return jpeg.tobytes()

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield(frame)
        time.sleep(1)

def index(request):
    # response = HttpResponse(gen(VideoCamera())
    return StreamingHttpResponse(gen(VideoCamera()),content_type="image/jpeg")

Answer

luvwinnie picture luvwinnie · Apr 3, 2018

@Ritwick What I have done is by changing the gen and index function to below

def gen(camera):
    while True:
        frame = camera.get_frame()
        yield(b'--frame\r\n'
        b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')

@gzip.gzip_page
def index(request): 
    try:
        return StreamingHttpResponse(gen(VideoCamera()),content_type="multipart/x-mixed-replace;boundary=frame")
    except HttpResponseServerError as e:
        print("aborted")

I use the python generator to generate every camera frame and using the StreamingHttpResponse to replace the multipart/x-mixed-replace which the boundary tagged as frame

In django there is a gzip decorator function.

from django.views.decorators import gzip

To improve the speed of Streaming. I used the django gzip decorator method to gzip the frame.