树莓派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
相关产品推荐
相关产品推荐

