python-3.x werkzeug.exceptions.BadRequestKeyError:400错误请求:浏览器(或代理)发送了一个请求,该服务器无法理解,KeyError:'video'

zte4gxcn  于 2023-11-20  发布在  Python
关注(0)|答案(1)|浏览(263)

我试图通过一个HTTP请求将一个实时视频流从JS传递到python进行人脸识别,我得到了错误werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'video'
在检查我的终端的应用程序的日志后,我看到流的数据类型为Bytes,我相信我需要在将其传递给python脚本之前将其转换为numpy数组。
我目前的实现如下:我在一个html模板上有我的JS代码,它打开一个POST请求到我的python文件,现在处理实时视频流以获取其中包含人脸的帧。
这是HTML和JS

`<button id="startBtn" onclick="openCam()">Open Webcam</button>
<br>
<!-- close button -->
<button id="closeButton" onclick="closeCam()">Close</button>
<br>
<!--video element to show the live video-->
<video id="video" autoplay></video>
<!-- javascript video stream -->
<script>
    const video = document.getElementById('video');
    const closeButton = document.getElementById('closeButton');

    const canvas = document.createElement('canvas');
    const context = canvas.getContext('2d');
    
    let intervalID;

    function openCam(){
        navigator.mediaDevices.getUserMedia({ video: true })
        .then((stream) => {
            video.srcObject = stream;
            intervalID = setInterval(() => {
            context.drawImage(video, 0, 0, canvas.width, canvas.height);
            const dataURL = canvas.toDataURL('image/jpeg');
            const xhr = new XMLHttpRequest();
            xhr.open('POST', '/markin');
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.send(`video=${encodeURIComponent(dataURL)}`);
            }, 1000 / 30);
        })
        .catch((error) => {
            console.error(error);
        });
    }

    // Close the live stream by removing the interval counter
    function closeCam(){
        // const stopButton = document.getElementById('stopButton');
        closeButton.addEventListener('click', () => {
        clearInterval(intervalID);
        video.srcObject.getTracks()[0].stop();
        window.location.href = "{{ url_for('markin') }}";    
    });
    }
</script>`

字符串
下面是代码的python端

`# get the video stream from the data request
data = request.form['video']
dataURL = request.form.get('video',False)
if dataURL is not null:
    print("DATA IS NOT EMPTY!!!")
    # print(dataURL)
    print(type(data))
    print(data)
else:
    print("DATA IS EMPTY!!!")
# Decode Base64-encoded video stream data
decoded_data = base64.b64decode(dataURL.split(',')[1])
img = decoded_data
if img is not null:
    print("IMAGE IS NOT EMPTY!!!")
    print(type(img))
    print(img)`


我已经尝试过将其他选项应用于实时视频流,如WebRTC,试图将其配置到我的应用程序中是一个相当艰难的过程,如果您提供它作为这个问题的解决方案,我将非常感谢一个更直接的例子。

watbbzwu

watbbzwu1#

该错误表明在请求的表单数据中找不到键video
下面的简单示例基本上是基于您的代码。从视频中提取的单个图像以文件的形式发送到服务器。在这里,人脸被识别并标记为矩形。然后图像被发送回客户端,在那里显示它们。

from flask import Flask, abort, render_template, request, send_file
from io import BytesIO
import cv2 as cv
import numpy as np
import os

face_classifier = cv.CascadeClassifier(
    os.path.join(
        cv.data.haarcascades, 
        'haarcascade_frontalface_default.xml'
    )
)

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.post('/process')
def process():
    file = request.files.get('image')
    if file:
        nparr = np.fromstring(file.read(), np.uint8)
        frame = cv.imdecode(nparr, cv.IMREAD_ANYCOLOR)
        frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

        faces = face_classifier.detectMultiScale(frame_gray, 1.3, 5)
        for (x,y,w,h) in faces:
            frame = cv.rectangle(frame, (x,y), (x+w, y+h), (0, 255, 0), 2) 

        _, buffer = cv.imencode('.jpg', frame)
        return send_file(
            BytesIO(buffer), 
            as_attachment=False, 
            mimetype='image/jpeg'
        )
    abort(400)

个字符

相关问题