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

如何在Python Django中将OpenCV输出推送到浏览器网页应用?

如何将OpenCV处理后的摄像头画面集成到网页中

Hey there! 看你已经搞定了本地的OpenCV人脸识别功能,现在要把这个带识别效果的摄像头画面放到网页里对吧?其实核心思路就是把OpenCV处理后的视频帧转换成可被网页接收的流格式,通过Web服务器推送给前端。下面我给你两种简单易上手的实现方案,都是基于Python后端的:


方案一:用Flask搭建轻量视频流服务

Flask是个简单的Python Web框架,适合快速搭建这类小服务:

  1. 先安装Flask:
pip install flask
  1. 把你原有的OpenCV代码修改成Flask服务形式,替换掉本地显示的逻辑,改成生成视频流:
import numpy as np
import cv2
import pickle
from flask import Flask, Response

app = Flask(__name__)

# 初始化你的人脸识别组件
face_cascade = cv2.CascadeClassifier('Cascades/data/haarcascade_frontalface_alt2.xml')
eye_cascade = cv2.CascadeClassifier('Cascades/data/haarcascade_eye.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainer.yml")

labels = {"person_name": 1}
with open("labels.pickle", 'rb') as f:
    orig_labels = pickle.load(f)
    labels = {v:k for k,v in orig_labels.items()}

cap = cv2.VideoCapture(0)

def generate_frames():
    """生成处理后的视频帧流"""
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        
        # 你的人脸识别逻辑(和原代码一致)
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=5)
        for (x, y, w, h) in faces:
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = frame[y:y+h, x:x+w]

            id_, confidence = recognizer.predict(roi_gray)
            if confidence >= 45 and confidence <= 85:
                font = cv2.FONT_HERSHEY_SIMPLEX
                color = (255, 255, 255)
                name = labels[id_]
                stroke = 2
                cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)

            color = (0, 255, 255) # BGR格式
            stroke = 2
            width = x + w
            height = y + h
            cv2.rectangle(frame, (x, y), (width, height), color, stroke)

            eyes = eye_cascade.detectMultiScale(roi_gray)
            for(ex,ey, ew, eh) in eyes:
                cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0, 255, 0), 2)
        
        # 将帧编码为JPEG格式,用于MJPEG流传输
        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()
        # 按照MJPEG流的格式返回帧
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

# 视频流接口
@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

# 主页,返回显示视频流的HTML页面
@app.route('/')
def index():
    return '''
    <html>
        <head>
            <title>APS Recognition</title>
        </head>
        <body>
            <h1>APS Face Recognition</h1>
            <img src="/video_feed" style="max-width: 800px;">
        </body>
    </html>
    '''

if __name__ == '__main__':
    try:
        app.run(debug=True)
    finally:
        # 程序结束时释放摄像头
        cap.release()
  1. 运行脚本,然后打开浏览器访问 http://localhost:5000,就能看到带人脸识别标记的摄像头画面了!

方案二:用FastAPI搭建高性能异步服务

如果你更喜欢现代的异步Web框架,FastAPI是个不错的选择,性能会更好一些:

  1. 安装依赖:
pip install fastapi uvicorn
  1. 修改后的代码:
import numpy as np
import cv2
import pickle
from fastapi import FastAPI, Response
from fastapi.responses import HTMLResponse

app = FastAPI()

# 初始化人脸识别组件
face_cascade = cv2.CascadeClassifier('Cascades/data/haarcascade_frontalface_alt2.xml')
eye_cascade = cv2.CascadeClassifier('Cascades/data/haarcascade_eye.xml')
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read("trainer.yml")

labels = {"person_name": 1}
with open("labels.pickle", 'rb') as f:
    orig_labels = pickle.load(f)
    labels = {v:k for k,v in orig_labels.items()}

cap = cv2.VideoCapture(0)

def generate_frames():
    while True:
        ret, frame = cap.read()
        if not ret:
            break
        
        # 你的人脸识别逻辑
        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
        faces = face_cascade.detectMultiScale(gray, scaleFactor=1.5, minNeighbors=5)
        for (x, y, w, h) in faces:
            roi_gray = gray[y:y+h, x:x+w]
            roi_color = frame[y:y+h, x:x+w]

            id_, confidence = recognizer.predict(roi_gray)
            if confidence >= 45 and confidence <= 85:
                font = cv2.FONT_HERSHEY_SIMPLEX
                color = (255, 255, 255)
                name = labels[id_]
                stroke = 2
                cv2.putText(frame, name, (x,y), font, 1, color, stroke, cv2.LINE_AA)

            color = (0, 255, 255) # BGR格式
            stroke = 2
            width = x + w
            height = y + h
            cv2.rectangle(frame, (x, y), (width, height), color, stroke)

            eyes = eye_cascade.detectMultiScale(roi_gray)
            for(ex,ey, ew, eh) in eyes:
                cv2.rectangle(roi_color, (ex,ey), (ex+ew, ey+eh), (0, 255, 0), 2)
        
        ret, buffer = cv2.imencode('.jpg', frame)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.get("/video_feed")
async def video_feed():
    return Response(generate_frames(), media_type="multipart/x-mixed-replace; boundary=frame")

@app.get("/", response_class=HTMLResponse)
async def root():
    return """
    <html>
        <head>
            <title>APS Recognition</title>
        </head>
        <body>
            <h1>APS Face Recognition</h1>
            <img src="/video_feed" style="max-width: 800px;">
        </body>
    </html>
    """

# 程序关闭时释放摄像头
@app.on_event("shutdown")
def shutdown_event():
    cap.release()
  1. 运行服务:
uvicorn main:app --reload

然后访问 http://localhost:8000 就能看到效果啦。


一些注意事项

  • 确保你的Cascades文件夹、trainer.yml、labels.pickle和脚本在同一个目录下,不然要修改代码里的文件路径
  • 如果是部署到远程服务器,需要服务器有可用的摄像头权限;如果是让用户在本地运行后端,就能直接调用用户自己的摄像头
  • MJPEG流的延迟相对会高一点,如果追求更低延迟,可以考虑用WebSocket传输帧,但MJPEG是最容易实现的方案,适合快速验证功能

内容的提问来源于stack exchange,提问作者eden10

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:58:07