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

如何将JavaScript捕获的摄像头图片传递给Python Flask应用处理

Flask+Mask RCNN网页摄像头截图处理方案

截图传递到Python的最简方案

你当前使用的方案就是最优解:

  • 前端通过Canvas捕获摄像头当前帧,转成Blob二进制图像对象
  • 用Fetch API将图像封装为FormData格式,POST提交到Flask后端接口
  • 后端处理完成后直接返回处理后的图像,前端接收后直接展示
    全程不需要用户额外操作,所有计算逻辑都保留在Python端,无需学习额外的JS图像处理库。

现有问题修复

问题1:处理效果仅显示在服务端面板,未叠加在返回截图上

问题根因:Mask RCNN的visualize.display_instances函数默认仅在服务端本地弹出窗口展示结果,不会返回带标注的图像数据,同时你没有处理RGB/BGR通道转换的问题。
后端upload接口修改如下:

# 全局初始化模型,不要每次请求都创建,避免卡顿
model = None

@app.route('/upload', methods=['POST'])
def upload():
    global model
    if request.method == 'POST':
        fs = request.files.get('snap')
        if fs:
            if not model:
                model = create_model()
            img = cv.imdecode(np.frombuffer(fs.read(), np.uint8), cv.IMREAD_UNCHANGED)
            # OpenCV默认是BGR,转成RGB给RCNN处理
            img_rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
            # 检测对象
            r = model.detect([img_rgb], verbose=0)[0]
            # 加return_image=True参数,让函数返回带标注的图像,不要本地展示
            masked_image = visualize.display_instances(
                img_rgb, r['rois'], r['masks'], r['class_ids'], 
                ["BG", "culture"], r['scores'], show_bbox=True,
                return_image=True
            )
            # 加计数文本
            masked_image = cv.putText(
                img=np.float32(masked_image), 
                text=f'{r["masks"].shape[2]} colonies', 
                org=(50, 50), fontFace=cv.FONT_HERSHEY_DUPLEX, 
                fontScale=2, lineType=cv.LINE_AA, 
                color=(255, 0, 0), thickness=2
            )
            # 转回BGR格式给OpenCV编码
            masked_image_bgr = cv.cvtColor(masked_image.astype(np.uint8), cv.COLOR_RGB2BGR)
            ret, buf = cv.imencode('.jpg', masked_image_bgr)
            return send_file_data(buf.tobytes())
    return 'error'

问题2:处理的是摄像头下一帧,而非点击时的当前截图

问题根因:新版HTML里设置了100ms的自动上传定时器,会持续把实时摄像头帧传到后端,你点击按钮的时候只更新了本地截图预览,并没有触发对应截图的上传,后端处理的还是定时器传过来的后续帧。
前端JS修改如下:
删掉这段自动上传的定时器代码:

//console.log('setInterval')
window.setInterval(function() {
    context.drawImage(video, 0, 0, {{ width }}, {{ height }});
    canvas.toBlob(upload, "image/jpeg");
}, 100);

修改按钮点击事件,点击时先绘制当前帧,再主动上传:

document.getElementById("send").addEventListener("click", function() {
    // 绘制当前摄像头帧到Canvas
    context.drawImage(video, 0, 0, {{ width }}, {{ height }});
    // 显示本地截图预览
    image64.src = canvas.toDataURL();
    // 上传当前截图到后端
    canvas.toBlob(upload, "image/jpeg");
});

修改完成后只有你点击按钮的时候才会上传当前帧,不会再处理后续的实时帧。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:09:03