How to stream opencv frame with django frame in realtime?
Asked Answered
A

1

9

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")
Affiche answered 27/8, 2017 at 15:19 Comment(3)
The client probably only expects a single image, since the content_type is image/jpeg. This question might be useful. #21198138Initiatory
Thank you for replying! I have been able to use multipart/x-mixed to stream my camera input frame!Affiche
Can you explain how you used multipart? or maybe have a code snippet? I have the same problem.Maracaibo
A
6

@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.

Affiche answered 3/4, 2018 at 2:34 Comment(5)
Is there any way to put forward this on a template? I have a webpage where I would like to run the above code and display the result on a sidebar of the page. Can you please let me know what changes I would need to do in the view and template?Monohydric
For a full example: blog.miguelgrinberg.com/post/video-streaming-with-flask/page/8Exteroceptor
@Abhijit, did you find a solution? I'm looking for the same.Jard
@Monohydric You can put <img src="{% url 'url-name' %}"></img> with the url-name being the name of the URL of the view index above. Here is a django app which does this: github.com/sawardekar/Django_VideoStreamAccouterment
@Affiche Is gzip decorator needed when we are using jpeg compressed format? And why stream sometimes not working in Safari and loading page freezes?Tepper

© 2022 - 2024 — McMap. All rights reserved.