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")
bruno desthuilliers
  • 68,994
  • 6
  • 72
  • 93
luvwinnie
  • 419
  • 6
  • 17
  • 1
    The client probably only expects a single image, since the content_type is `image/jpeg`. This question might be useful. https://stackoverflow.com/questions/21197638/create-a-mjpeg-stream-from-jpeg-images-in-python – Håken Lid Aug 27 '17 at 15:32
  • Thank you for replying! I have been able to use multipart/x-mixed to stream my camera input frame! – luvwinnie Aug 28 '17 at 07:25
  • Can you explain how you used multipart? or maybe have a code snippet? I have the same problem. – Archetype2142 Apr 02 '18 at 14:18

1 Answers1

5

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

luvwinnie
  • 419
  • 6
  • 17
  • 1
    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? – Abhijit Oct 22 '18 at 11:35
  • For a full example: https://blog.miguelgrinberg.com/post/video-streaming-with-flask/page/8 – Emil Terman Jul 06 '19 at 13:34
  • @Abhijit, did you find a solution? I'm looking for the same. – Miguel Sep 17 '19 at 21:16
  • 1
    @Abhijit You can put `` with the `url-name` being the name of the URL of the view `index` above. Here is a django app which does this: https://github.com/sawardekar/Django_VideoStream – Sayyor Y Mar 11 '21 at 07:42