Как передать переменную из video view1 (которая находится внутри view2) в шаблон view2 в Django

#django #django-views #video-streaming #streaminghttpresponse

#django #django-просмотры #потоковое видео #потокhttpresponse

Вопрос:

У меня есть представление home :

 def home(request):
    return render(request, 'detection/home.html')
 

И вот его «шаблон templates/detection/home.html:

 {% extends "detection/base.html" %}

{% block content %}

<h1>Camera View</h1>

<img src="{% url 'cam-feed' %}"></img>

{% endblock content %}
 

который основан на templates/detection/base.html

 <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    {% block content %}
    {% endblock content %}
</body>
</html>
 

На этой странице, как видно из home.html , я показываю вывод камеры с помощью view cam_feed :

 def cam_feed(request):
    return StreamingHttpResponse(gen(VideoCamera(), content_type="multipart/x-mixed-replace;boundary=frame")
 

который использует класс VideoCamera , который является классом OpenCV, для отображения камеры и который выводит prediction переменную в get_frame :

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

    def __del__(self):
        self.video.release()

    def get_frame(self):
        _, image = self.video.read()

        ### All the detections

        # Person Existence Classification
        # RGB_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        im = Image.fromarray(image)
        im = im.resize((128, 128))
        img_array = np.array(im)
        img_array = np.expand_dims(img_array, axis=0)
        prediction = int(model.predict(img_array)[0][0])
        
        _, jpeg = cv2.imencode('.jpg', image)
        return jpeg.tobytes()
 

cam_feed также использует функцию gen , которая передает вывод камеры в соответствующей форме:

 def gen(camera):
    while True:
        frame = camera.get_frame()
        yield(b'--framern'
              b'Content-Type: image/jpegrnrn'   frame   b'rnrn')
 

Как я могу отправить переменную prediction , возвращенную из VideoCamera класса выше (предпочтительно каждый раз, когда принимается новый кадр и выполняется прогнозирование), в template home.html , чтобы я мог вывести ее для просмотра пользователем. Я знаю, что обычно я могу передать словарь context home.html , но я не вижу способа передать его из функции gen в view home , поскольку он вызывается внутри StreamingHttpResponse, который вызывается в <img> теге of home.html .

Ответ №1:

Если вы хотите получить прогноз только для одного кадра, разве вы не можете просто добавить метод для прогнозирования и вызвать этот метод в представлении шаблона следующим образом?:

 # where VideoCamera is defined:
class VideoCamera(object):
    def __init__(self):
        self.video = cv2.VideoCapture(0)

    def __del__(self):
        self.video.release()

    def get_frame(self):
        # unchanged...

    def get_prediction(self):
        _, image = self.video.read()

        ### All the detections

        # Person Existence Classification
        # RGB_img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        im = Image.fromarray(image)
        im = im.resize((128, 128))
        img_array = np.array(im)
        img_array = np.expand_dims(img_array, axis=0)
        prediction = int(model.predict(img_array)[0][0])
        return prediction

# in views.py:
def home(request):
    cam = VideoCamera()
    prediction = cam.get_prediction()
    return render(request, 'detection/home.html', context={'prediction': prediction})
 

Также вы можете посмотреть django-channels

Комментарии:

1. На самом деле я не хочу получать прогноз только для одного кадра. Я хочу, чтобы прогнозы печатались каждый раз, когда камера получает следующий кадр (или, по крайней мере, каждый определенный интервал времени). Но ваше решение печатает только предсказание первого кадра. Извините, если я не был ясен в своем вопросе.

2. Да, я изучаю django-каналы. Было бы здорово, если бы вы могли показать мне, как настроить все это для этой конкретной проблемы.

3. Я действительно не эксперт ни в чем из этого, но я обнаружил, что глава об установке в документации по каналам достаточно проста для понимания, если вы только хотите поэкспериментировать с ней.

4. Если вы хотите постоянно обновлять прогноз для клиента, возможно, вы можете каким-то образом закодировать его с помощью фрейма и снова разделить его на стороне клиента с помощью js или чего-то еще, что вы хотите там использовать.