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

Python OpenCV配合Arduino触发存图运行速度慢该如何优化?

代码优化方案

核心问题原因

  • OpenCV的VideoCapture默认启用多帧缓存,每次读取的是数秒前的缓存帧,不是实时数据,导致状态和画面不同步
  • 串口读取逻辑未设置超时/缓存清理,Arduino发送的开关数据积压在串口缓冲区,程序读到的是十几秒前的旧数据,这是15秒延迟的核心诱因
  • 代码执行顺序错误:先展示1080P原始帧再做resize,浪费算力;开关检测放在帧读取处理之后,优先级不够
  • 循环固定等待40ms(即25帧上限),没有清串口缓存的逻辑,延迟持续累积
  • 原代码保存图片时直接覆盖同路径文件,没有按计数区分,会导致历史拍摄结果丢失

优化后代码

import os
import cv2
# 若你使用自定义封装的SerialObject类,替换对应串口接口即可
import serial

# 初始化串口,设置10ms超时,非阻塞读取避免卡死
Arduino = serial.Serial('你的串口号', 对应波特率, timeout=0.01)

if os.path.exists(PathCouleur) and os.path.exists(PathGris):
    # Windows环境用CAP_DSHOW、Linux用CAP_V4L2、Mac用CAP_AVFOUNDATION,走原生驱动避免系统层缓存
    Images = cv2.VideoCapture(Camera, cv2.CAP_DSHOW)
    # 摄像头只保留1帧缓存,每次读都是最新实时帧
    Images.set(cv2.CAP_PROP_BUFFERSIZE, 1)
    # 摄像头参数设置
    Images.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
    Images.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
    Images.set(cv2.CAP_PROP_BRIGHTNESS, Brightness)

    Compte = 0
    Switch = "0"

    while True:
        # 先清空串口积压数据,只取最新的开关值
        while Arduino.in_waiting > 0:
            Switch = Arduino.readline().decode('utf-8').strip()
        
        # 读取实时帧
        Sucess, Video = Images.read()
        if not Sucess:
            continue
        
        # 先做resize,后续预览、检测都用小帧,节省算力
        Video_resized = cv2.resize(Video, (Largeur, Hauteur))
        # 预览用小帧即可,不需要渲染1080P大画面
        cv2.imshow("Camera", Video_resized)
        
        # 开关触发逻辑
        if Switch == "1":
            blur = cv2.Laplacian(Video_resized, cv2.CV_64F).var()
            if blur < MinBlur:
                # 按计数命名保存文件,避免覆盖
                cv2.imwrite(f"{PathCouleur}_{Compte}.png", Video_resized)
                cv2.imwrite(f"{PathGris}_{Compte}.png", cv2.cvtColor(Video_resized, cv2.COLOR_BGR2GRAY))
                Compte += 1
                # 触发后重置开关状态、清空串口缓存,避免重复触发
                Switch = "0"
                Arduino.reset_input_buffer()

        # waitKey只等1ms,提高循环响应速度
        if cv2.waitKey(1) == 27:
            break

    # 释放所有资源
    Images.release()
    Arduino.close()
    cv2.destroyAllWindows()
else:
    print("Erreur, aucun Path")

补充说明

如果你的SerialObject是自定义封装的串口类,只需要把代码中串口读取、缓存清理的部分替换为你封装类对应的接口即可,核心优化逻辑不变。优化后开关响应延迟可以降到100ms以内,完全满足实时拍摄需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:36:03