如何在OpenCV定时拍照while循环中实现按q终止、按p即时拍照
适配Windows系统的按键功能实现方案
Windows环境下直接用
cv2.waitKey实现即可,无需引入需要额外权限的keyboard库,也不存在跨平台权限冲突。需要注意cv2.waitKey依赖OpenCV创建的窗口接收键盘事件,你可以创建一个隐藏的极小窗口,完全不影响正常运行。
核心修改逻辑
- 把原代码中整段1小时的
time.sleep(time_step)拆分为每100ms检测一次按键的循环,避免长睡眠期间按键无响应 - 将拍照逻辑封装为独立函数,定时触发和手动p键触发可以复用代码,无需重复写逻辑
- 按键检测逻辑直接嵌在等待间隔的循环里,不需要修改原有定时拍照的执行流程
修改后的完整代码
import time import cv2 import numpy as np # 提前创建接收按键事件的窗口,默认缩到最小不占空间 cv2.namedWindow("key_monitor", cv2.WINDOW_NORMAL) cv2.resizeWindow("key_monitor", 1, 1) # 不需要显示窗口的话取消下面这行注释即可完全隐藏 # cv2.setWindowProperty("key_monitor", cv2.WND_PROP_VISIBLE, cv2.WINDOW_FALSE) # 封装拍照逻辑复用 def take_photo(crit): cap.open(num_cam, api) cap.set(cv2.CAP_PROP_FOCUS, 70) ret = cap.grab() if ret: tst, frm = cap.retrieve() cv2.imwrite(f'test1h_{np.round(crit,2)}_f70.png', frm) cap.release() # 原有参数初始化,你原来的变量值直接沿用即可 t0 = time.perf_counter() time_max = 3600 * 24 * 14 time_step = 3600 cap = cv2.VideoCapture() num_cam = 0 # 替换为你的摄像头编号 api = cv2.CAP_ANY # 替换为你的api参数 while True: tc = time.perf_counter() crit = tc - t0 if crit > time_max: cap.release() cv2.destroyAllWindows() break # 执行定时拍照 take_photo(crit) # 替换原有的time.sleep,加入按键检测 wait_start = time.perf_counter() while time.perf_counter() - wait_start < time_step: # 每100ms检测一次按键 key = cv2.waitKey(100) & 0xFF if key == ord('q'): # 按q直接退出 cap.release() cv2.destroyAllWindows() exit() elif key == ord('p'): # 按p触发即时拍照 current_crit = time.perf_counter() - t0 take_photo(current_crit) pass
注意事项
- 按p触发的手动拍照不会打乱原有1小时的定时节奏,下一次定时拍照仍会按原时间点执行
- 全程不需要管理员权限,Windows下直接运行即可
- 如果需要实时预览画面,可以在拍照逻辑中加一行
cv2.imshow("key_monitor", frm)即可
内容的提问来源于stack exchange,提问作者jane doe
相关产品推荐
相关产品推荐

