检测到人脸时MQTT发布消息
Mqtt publishing message when face is detected
我正在做一个结合 MQTT 和人脸识别的大学项目,使用 raspberry pi。
首先,我想说的是,人脸识别在单独 运行 时可以正常工作,但在将它与 MQTT 一起应用时,我遇到了一些问题。
在 Try 部分,当一个人被识别或未知时,它每 3 秒发布一次非常好。
奇怪的是,如果我把手放在摄像头前或超出范围,它会继续发送它识别出的最后一个人的 ID。
我希望它要么什么都不做,要么发布 none。
有解决这个问题的想法或建议吗?
提前致谢
编辑 1:基本上正如我所想的那样,它必须与人脸识别部分做更多的事情。当仅使用 opencv 的人脸识别代码时,它 运行s 很顺利。但是当我把手放在相机前面或离开时,事情就变得复杂了,因为捕捉在它看到的最后一件事上冻结了,所以它一直在 printing/publishing 相同的东西上。目前还没有想出办法避免这种情况。任何帮助将不胜感激
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)
我正在做一个结合 MQTT 和人脸识别的大学项目,使用 raspberry pi。 首先,我想说的是,人脸识别在单独 运行 时可以正常工作,但在将它与 MQTT 一起应用时,我遇到了一些问题。
在 Try 部分,当一个人被识别或未知时,它每 3 秒发布一次非常好。 奇怪的是,如果我把手放在摄像头前或超出范围,它会继续发送它识别出的最后一个人的 ID。
我希望它要么什么都不做,要么发布 none。
有解决这个问题的想法或建议吗? 提前致谢
编辑 1:基本上正如我所想的那样,它必须与人脸识别部分做更多的事情。当仅使用 opencv 的人脸识别代码时,它 运行s 很顺利。但是当我把手放在相机前面或离开时,事情就变得复杂了,因为捕捉在它看到的最后一件事上冻结了,所以它一直在 printing/publishing 相同的东西上。目前还没有想出办法避免这种情况。任何帮助将不胜感激
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)