Passing a cv2 frame from view to template

Viewed 2872

Basically, my django app needs to create an image in a view, and pass that to a template. This is easy for a string, but I can't find a way to do it with an image. I have read many stack overflow threads but none quite like mine, which is surprising.

I was trying variations of this as my view:

views.py:

def index(request):
  while (True):

    #video_capture = cv2.VideoCapture(0)
    #ret, frame = video_capture.read()

    img = "D:/Desktop/Tap/bsnsFaces.jpg"
    frame = cv2.imread(img)
    facesNumber ="Found {0} faces!".format(len(faces))

    return render(request, 'result.html', {'p': facesNumber}, {'img': frame})`

With the {'img':frame} part at the end not being anywhere close to right. I tried a few things that I found on SO but nothing worked so far. I know that the image is static but eventually I want this to be a frame captured from a webcam so I can't solve this by using models (or can I?).

Thanks in advance for any advice!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Face detection with Django</title>
    <p>{{ p }}</p>
    <img src="data:image/jpg;base64, {{ img }}"></img>
</head>
<body>

</body>
</html>
1 Answers

I would suggest base64 encoding the frame and passing that string. That way you can pass the dynamically generated image from the views to the result.html to render. You can then display the base64 image in the result.html.

views.py

import cv2
import base64

def index(request):
  #while (True): #Note: This loop is pointless, it will break when you return.

    #video_capture = cv2.VideoCapture(0)
    #ret, frame = video_capture.read()

    img = "D:/Desktop/Tap/bsnsFaces.jpg"
    frame = cv2.imread(img)
    ret, frame_buff = cv2.imencode('.jpg', frame) #could be png, update html as well
    frame_b64 = base64.b64encode(frame_buff)
    facesNumber ="Found {0} faces!".format(len(faces))

    # Note this was fixed to be one dict with the context variables
    return render(request, 'result.html', {'p': facesNumber, 'img': frame_b64})

result.html

   <img src="data:image/jpeg;base64, {{img}}"></img>

Just a note based on your while loop, if you want to be updating the page constantly from the webcam, this should be done clientside. Otherwise you will need to be constantly refreshing the page to see image updates. The client (result.html) can poll the server with AJAX for image updates, and refresh itself without actually reloading the entire result.html page.

Related