python - 在不影响其余代码的情况下暂停 GPIO.output
问题描述
我正在开发一个来自 IP 摄像机视频流的实时人脸识别程序,该程序在识别人脸时触发 GPIO 信号。首次识别出人脸后,我需要在一定时间内(例如 45 秒)不激活 GPIO。
我尝试time.sleep(45)
在触发 GPIO 信号后插入,这似乎可以工作,但在暂停 45 秒后,正在分析的视频流不再直播。它从识别面部后的那一帧开始,换句话说,延迟了 45 秒。
我怎样才能将 GPIO 输出暂停 45 秒,然后返回到正在分析的实时视频流?
import cv2
import numpy as np
import os
import time
import RPi.GPIO as GPIO
relay = 23
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(relay, GPIO.OUT)
GPIO.output(relay, 1)
recognizer = cv2.face.LBPHFaceRecognizer_create()
recognizer.read('trainer/trainer.yml')
cascadePath = "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascadePath);
font = cv2.FONT_HERSHEY_SIMPLEX
#initiate id counter
id = 0
# names related to ids: example ==> Jenifer: id=1, etc
names = ['None', 'Jenifer', 'Jenifer', 'Luciola']
# Initialize and start realtime video capture
cam = cv2.VideoCapture('ipcamera')
frame_rate = 1
prev = 0
# Define min window size to be recognized as a face
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
while True:
time_elapsed = time.time() - prev
res, image = cam.read()
if time_elapsed > 1./frame_rate:
prev = time.time()
ret, img =cam.read()
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(
gray,
scaleFactor = 1.2,
minNeighbors = 5,
minSize = (int(minW), int(minH)),
)
for(x,y,w,h) in faces:
cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2)
id, confidence = recognizer.predict(gray[y:y+h,x:x+w])
# Check if confidence is less than 100 ==> "0" is perfect match
if (confidence < 85):
id = names[id]
confidence = " {0}%".format(round(100 - confidence))
GPIO.output(relay, 0)
print("Ouverture du portail")
time.sleep(1)
GPIO.output(relay, 1)
else:
GPIO.output(relay, 1)
cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2)
cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1)
cv2.imshow('camera',img)
k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video
if k == 27:
break
# Do a bit of cleanup
print("\n [INFO] Exiting Program and cleanup stuff")
cam.release()
cv2.destroyAllWindows()
Possum 的解决方案效果很好。第 66 行:
GPIO.output(relay, 1)
cam.release()
time.sleep(45)
cam = cv2.VideoCapture('ipcamera')
else:
解决方案
您可以使用threading.Thread
创建一个线程来在后台运行相机流,因此它将不受该sleep
函数的影响。你可以这样做:
from threading import Thread
import cv2
gray = None
minW = None
minH = None
def camera_stream():
def get_frames():
while True:
global minW
global minH
cv2.VideoCapture('ipcamera')
minW = 0.1*cam.get(3)
minH = 0.1*cam.get(4)
res, image = cam.read()
gray_frame = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
yield gray_frame
while True:
global gray
gray = next(get_frames)
thread = Thread(target=camera_stream, daemon=True)
thread.start()
...
现在,无论您在哪里使用变量gray
,它都应该使用在后台不断运行的摄像机流中的下一帧。
推荐阅读
- java - 为什么从 Firebase 让 Uid 不起作用?
- swift - 如何更改 CVPixelBuffer 数据格式
- c# - 发布传递空模型值以及如何正确删除或修复它?
- javascript - 由于 angulat6 中的撇号符号而无法显示图像
- java - 如何将android库项目转换为fat jar
- node.js - 使用另一台主机中的副本集连接到 mongodb 集群时出错
- google-maps - 使用电子表格中的 API 密钥进行身份验证
- r - 在 R 中运行样本大小不等的两样本 t.test
- android - Kotlin 不理解 ViewModelProviders.of(activity ?: fragment)
- c# - 无法转换类型 func
布尔