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

树莓派4按钮触发LED亮灯拍照问题:首张照片LED未点亮

问题描述

我正在开展一项实验:按下按钮后,LED需点亮0.5秒,并在LED点亮期间(例如0.25秒时)拍摄照片。初期编写了无时间限制的LED点亮时拍照代码,但实际拍摄的照片中,只有从第二张开始能看到LED处于点亮状态,首张照片的LED并未点亮。尝试在拍照前添加time.sleep(1)以及使用cv2.waitKey(1),均无效果,急需解决办法!

现有代码
import RPi.GPIO as GPIO
import cv2
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(16, GPIO.OUT)


GPIO.output(12, GPIO.LOW)
GPIO.output(16, GPIO.LOW)
time.sleep(1)
cam = cv2.VideoCapture(0)
s = 0


    
while True:
    ret, image = cam.read()
    cv2.imshow("Image Test",image)
    if GPIO.input(10) == GPIO.HIGH:
        s+=1
        GPIO.output(16,GPIO.HIGH)
        time.sleep(0.1)
        cv2.imwrite("/home/richgapple/Desktop/python/test%d.jpg" % s, image)
        print("Image must be taken")
        print(GPIO.input(10))

    else:
        GPIO.output(16,GPIO.LOW)
        
    if cv2.waitKey(1)& 0xFF == ord('b'):
        break
    
cam.release()
cv2.destroyAllWindows()
问题原因与解决方案

原因分析

首张照片拍不到亮灯的核心是帧缓存问题:检测到按钮按下时,用来保存的image是按下按钮前就已经读取好的帧——也就是LED点亮前的画面。第二次按下时,摄像头已经在循环中持续读取新帧,此时的帧是LED点亮后的画面,所以能拍到亮灯状态。

解决代码

调整逻辑顺序,先点亮LED并等待稳定,再读取新帧保存,同时添加防重复触发机制,严格匹配实验的0.5秒点亮时长要求:

import RPi.GPIO as GPIO
import cv2
import time

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(12, GPIO.OUT)
GPIO.setup(16, GPIO.OUT)

GPIO.output(12, GPIO.LOW)
GPIO.output(16, GPIO.LOW)
time.sleep(1)
cam = cv2.VideoCapture(0)
s = 0
button_pressed = False  # 防止按住按钮连续触发拍照

while True:
    # 持续读取帧用于实时预览
    ret, preview_frame = cam.read()
    cv2.imshow("Image Test", preview_frame)
    
    btn_state = GPIO.input(10)
    if btn_state == GPIO.HIGH and not button_pressed:
        button_pressed = True
        s += 1
        # 1. 点亮LED
        GPIO.output(16, GPIO.HIGH)
        # 2. 等待0.25秒,到达实验要求的点亮期间拍照节点
        time.sleep(0.25)
        # 3. 读取当前新帧(此时LED已稳定点亮)
        ret, capture_frame = cam.read()
        if ret:
            cv2.imwrite(f"/home/richgapple/Desktop/python/test{s}.jpg", capture_frame)
            print(f"第{s}张照片已拍摄")
        # 4. 继续保持LED点亮0.25秒,总时长达到0.5秒
        time.sleep(0.25)
        # 5. 熄灭LED
        GPIO.output(16, GPIO.LOW)
    elif btn_state == GPIO.LOW:
        button_pressed = False  # 按钮松开后重置状态
        
    if cv2.waitKey(1) & 0xFF == ord('b'):
        break
    
cam.release()
cv2.destroyAllWindows()

关键改动说明

  • 分离预览帧与拍摄帧:预览帧用于实时显示,拍摄帧在LED点亮后重新读取,确保拍到的是亮灯后的实时画面。
  • 添加状态锁:用button_pressed变量避免按住按钮时连续拍照,符合单次按下拍一张的操作逻辑。
  • 严格匹配实验时长:LED点亮后先等0.25秒拍照,再保持0.25秒熄灭,总点亮时长刚好0.5秒。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 22:25:01