首页 > 解决方案 > 在不影响其余代码的情况下暂停 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:

标签: pythongpio

解决方案


您可以使用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,它都应该使用在后台不断运行的摄像机流中的下一帧。


推荐阅读