簡體   English   中英

檢測到人臉時,Mqtt發布消息

[英]Mqtt publishing message when face is detected

我正在使用樹莓派將MQTT和人臉識別結合在一起的大學項目。 首先,我想說的是,人臉識別在單獨運行時可以正常工作,但是在將其與MQTT結合使用時,我遇到了一些麻煩。

在“嘗試”部分中,當某個人被識別或未知時,每3秒發布一次就可以了。 奇怪的是,如果我將手放在相機前面或超出范圍,它將繼續發送已識別出的最后一個人的ID。

我希望它什么都不做或什么都不發表。

有什么想法或建議解決此問題嗎? 提前致謝

編輯1:基本上,正如我所知道的,它必須在面部識別部分上做更多的工作。 當僅使用使用opencv的人臉識別代碼時,它可以平穩運行。 但是當我將手放在相機前或離開相機時,事情變得復雜了,因為捕獲的圖像凍結在最后看到的東西上,因此它會繼續打印/發布相同的東西。 尚未找到避免這種情況的方法。 任何幫助,將不勝感激

import cv2
import json
import time
import datetime as dt
import paho.mqtt.client as mqtt


detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
recognizer = cv2.face.LBPHFaceRecognizer_create()

broker = "*****"
port = *****
username = '*****'
password = '*****'


def on_connect(client, userdata, flags, rc):
    print("Connected with code: ", rc)
    client.subscribe('test/#')


def on_message(client, userdata, msg):
    print(str(msg.payload))


client = mqtt.Client("Python1")
client.on_connect = on_connect
client.on_message = on_message

client.username_pw_set(username, password)
client.connect(broker, port, 60)

client.loop_start()
time.sleep(1)


def facerecognizer():

    recognizer.read("trainerdir/training.yml")

    font = cv2.FONT_HERSHEY_SIMPLEX

    # Loading data

    with open('data.json', 'r') as f:
        names = json.load(f)

    # reverse the data
    # NOTE: for k, v !!
    # else it raises error !
    names = {v: k for k, v in names.items()}
    # print(names)
    print("[INFO] Face recognition is starting..")

    cap = cv2.VideoCapture(0)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)

    try:

        while True:

            ret, img = cap.read()

            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

            faces = detector.detectMultiScale(gray,
                                              scaleFactor=1.3,
                                              minNeighbors=5
                                              # minSize = (20,20)
                                              )

            for (x, y, w, h) in faces:
                cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

                roi_gray = gray[y:y + h, x:x + w]
                roi_color = img[y:y + h, x:x + w]

                ID, confidence = recognizer.predict(roi_gray)

                if (confidence < 100):

                    ID = names[ID]

                    confidence = "{}%".format(round(100 - confidence))

                    while True:
                        client.publish("Tutorial/", ID + " " + str(dt.datetime.now()))
                        print('ID sent')
                        time.sleep(3)

                    else:
                        client.publish("Tutorial/", 'None')
                        print('ID sent')
                        time.sleep(3)

                    client.loop_forever()

                else:
                    ID = "Unkown"
                    confidence = "{}%".format(round(100 - confidence))
                    print(ID, dt.datetime.now())
                    while True:
                        client.publish("Tutorial/", ID + " " + str(dt.datetime.now()))
                        print('ID sent')
                        time.sleep(3)
                    else:
                        client.publish("Tutorial/", 'None')
                        print('ID sent')
                        time.sleep(3)

                    client.loop_forever()

    # except UnboundLocalError:
    #     print("Error occured. Exitting..")

    except KeyboardInterrupt:
        pass
    except KeyError as K:
        print(K)
        print('[INFO] Name Value is a string and not an integer')

    print("[INFO] Exiting program..")
    cap.release()

從mqtt客戶端的文檔中,您似乎在濫用client.loop_forever()方法。

http://www.steves-internet-guide.com/loop-python-mqtt-client/

TLDR

  • 在循環中使用client.loop(timeout)來控制更新的處理。
  • 使用client.loop_start()啟動一個新線程,該線程為您處理更新。
  • 使用client.loop_forever()阻止和處理更新。

由於您已經調用了client.loop_start() ,因此無需調用loop_forever() 從代碼中刪除這些調用應該可以解決問題。

旁注:您的time.sleep(3)調用可以移至循環的末尾,因為無論采用哪種條件路徑都應該發生。

通過使用if True:而不是while True:我修復了它。 我還刪除了subclient.loop_forever(),它工作正常。 這是與我發布到問題中的代碼不同的示例代碼

   for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

        roi_gray = gray[y:y + h, x:x + w]
        # roi_color = img[y:y + h, x:x + w]

        ID, confidence = recognizer.predict(roi_gray)

        # 0 is 100% accuracy , and 100 is 0% accuracy
        if (confidence < 100):

            ID = names[ID]
            if True:

                subclient.publish("project/IDReceiver", ID + " " + str(dt.datetime.now()))

                print('ID sent')
                time.sleep(3)

            # subclient.loop_forever()

        else:
            ID = "Unknown"
            if True:

                subclient.publish("project/IDReceiver", "Unknown " + str(dt.datetime.now()))

                print('ID sent')
                time.sleep(3)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM