You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django摄像头人脸采集识别报错及人脸框选功能实现问询

解决方案

一、解决「TypeError: Object of type bytes is not JSON serializable」错误

这个错误核心是视图中尝试用JsonResponse返回字节类型数据,而JSON仅支持字符串、数字、数组、对象等可序列化类型。解决思路是将图片数据转为Base64字符串传输:

1. 前端调整:将摄像头帧转为Base64字符串发送

修改JS代码,把canvas捕获的帧转为Base64格式(去掉data:image/jpeg;base64,前缀)后发送给后端:

// 采集摄像头帧并发送
function captureFrame() {
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');
    const video = document.getElementById('video');
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
    // 转为Base64并去掉前缀
    const imageData = canvas.toDataURL('image/jpeg').split(',')[1];
    
    fetch('/recognize/', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': getCsrfToken()
        },
        body: JSON.stringify({image: imageData})
    })
    .then(response => response.json())
    .then(data => displayResult(data));
}

// 获取CSRF令牌
function getCsrfToken() {
    return document.querySelector('[name=csrfmiddlewaretoken]').value;
}

2. 后端视图调整:解码Base64并返回Base64格式的处理后图片

修改Django视图,接收Base64字符串解码为字节处理,再将处理后的图片转为Base64返回:

import base64
import cv2
import numpy as np
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def recognize_face(request):
    if request.method == 'POST':
        image_data = request.json.get('image')
        if not image_data:
            return JsonResponse({'error': '未接收到图片数据'}, status=400)
        
        # 解码Base64为字节
        img_bytes = base64.b64decode(image_data)
        nparr = np.frombuffer(img_bytes, np.uint8)
        img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
        
        # 调用人脸识别类处理
        fr = FaceRecognition()
        result_img, message = fr.detect_and_draw_face(img)
        
        # 将处理后的图片转为Base64
        _, buffer = cv2.imencode('.jpg', result_img)
        img_base64 = base64.b64encode(buffer).decode('utf-8')
        
        return JsonResponse({
            'processed_image': img_base64,
            'message': message
        })
    return JsonResponse({'error': '请求方法无效'}, status=405)

3. 调整FaceRecognition类的处理方法

确保类方法接收OpenCV格式图片,绘制人脸框后返回处理后的图片和提示信息:

import cv2

class FaceRecognition:
    def __init__(self):
        self.face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    
    def detect_and_draw_face(self, img):
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faces = self.face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
        
        message = "未检测到人脸"
        if len(faces) > 0:
            message = f"检测到{len(faces)}张人脸"
            # 绘制绿色人脸框
            for (x, y, w, h) in faces:
                cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
        
        return img, message

二、实现人脸框绘制与采集提示功能

1. 前端HTML结构

添加视频、画布、结果展示元素:

<!DOCTYPE html>
<html>
<head>
    <title>人脸采集识别</title>
</head>
<body>
    <video id="video" width="640" height="480" autoplay></video>
    <canvas id="canvas" width="640" height="480" style="display: none;"></canvas>
    <div id="result-area">
        <img id="processed-img" src="" alt="处理后的图片">
        <p id="tip-text"></p>
    </div>
    <button onclick="startCamera()">开启摄像头</button>
    <button onclick="captureFrame()">采集识别</button>
    
    {% csrf_token %}
    <script>
        // 插入之前的JS代码
    </script>
</body>
</html>

2. 前端添加摄像头初始化与结果展示函数

在JS中补充以下代码:

// 开启摄像头
function startCamera() {
    navigator.mediaDevices.getUserMedia({ video: true })
    .then(stream => {
        document.getElementById('video').srcObject = stream;
    })
    .catch(err => {
        console.error('摄像头开启失败:', err);
        alert('无法访问摄像头,请检查权限设置');
    });
}

// 展示处理结果
function displayResult(data) {
    const imgEl = document.getElementById('processed-img');
    const tipEl = document.getElementById('tip-text');
    
    imgEl.src = `data:image/jpeg;base64,${data.processed_image}`;
    tipEl.textContent = data.message;
}

关键注意事项

  • CSRF验证:Django默认开启CSRF保护,必须确保HTML中存在{% csrf_token %}标签,请求携带令牌。
  • 性能控制:若需实时识别,可设置定时器(如每500ms发送一次请求),避免高频请求压垮后端。
  • 浏览器兼容性:getUserMediaAPI需在HTTPS环境下使用(本地http://localhost除外),确保用户浏览器支持该API。

内容的提问来源于stack exchange,提问作者André Pimentel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 22:40:55