我正在尝试制作一个系统,向我的 ESP8266 发布一个“1”,这将点亮它的内置 LED,尽管我没有成功做到这一点。
我知道我需要检测图像中是否有任何人脸,但我不知道如何正确编写这部分代码
import cv2 as cv
import numpy as np
print("\n\n Programa iniciando", end='\n\n\n')
from paho.mqtt import client as mqtt_client
broker = 'test.mosquitto.org'
port = 1883
topic = "placasdecar1"
# Generate a Client ID with the publish prefix.
client_id = "pythonmqtt"
username = ''
password = ''
cascata_rosto = cv.CascadeClassifier("Markus\..PROG_DO_VS\haarcascade_frontalface_default.xml")
cascata_olhos = cv.CascadeClassifier("Markus\..PROG_DO_VS\haarcascade_eye.xml")
cap = cv.VideoCapture(0)
# ip = "https://192.168.1.75:8080/video"
# cap.open(ip)
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
client.loop_stop()
def connect_mqtt():
global mensagem
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
# client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
def subscribe(client: mqtt_client):
def on_message(client, userdata, msg):
print("Mensagem recebida:" , mensagem)
client.subscribe(topic)
client.on_message = on_message
def publish(client):
mensagem = ""
result = client.publish(topic, mensagem)
result
img = cap
while 1:
ret, img = cap.read()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
faces = cascata_rosto.detectMultiScale(gray, 1.5, 5)
psicoldelic = cv.cvtColor(img, cv.COLOR_BGR2BGRA)
# cada uma dessas coordenadas significa um inicio e fim
for (x,y,w,h) in faces:
# marcação de linhas em azul
cv.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
# roi significa região de interesse, no caso, a area de captura dessa cor
# ai estão as coordenadas de captura
roi_gray = gray[y:y+h, x:x+w]
roi_psicodelic = psicoldelic[y:y+h, x:x+h]
# ele marcou as coordenadas na imagem agora
roi_color = img[y:y+h, x:x+w]
eyes = cascata_olhos.detectMultiScale(roi_psicodelic)
for (ex,ey,ew,eh) in eyes:
cv.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,255,0),2)
if (cv.rectangle in img == True):
mensagem = "1"
run()
else:
mensagem = "0"
img = cv.resize(img,(1080, 640))
cv.imshow('img',img)
k = cv.waitKey(10) & 0xff
if k == 5:
break
cap.release()
cv.destroyAllWindows()
arduino IDE 代码相当简单,基本上就是 MQTT 库 + ESPWifi 库这部分代码:
if lastmessage == "1"{
digitalWrite(LED_BUILTIN, LOW);
} else {
digitalWrite(LED_BUILTIN, HIGH):
}
是的,我知道低通常意味着“没有光”,但这是一个不同的情况,这是有效的,我可以保证它。
我试图找出一种方法:如果有一张脸,则发送 1 到 MQTT,然后 ESP 会读取该信息并点亮 LED。 Arduino 代码工作正常,我的问题出在 Python 上。
您的 Python 代码似乎大部分已就位,但需要解决一些问题才能使其按预期工作。以下是您需要进行的更改的分步细目:
人脸检测条件:
条件 if (cv.rectangle in img == True): 不是检查是否检测到人脸的正确方法。相反,您应该检查面孔列表的长度。
MQTT 发布:
发布功能当前正在发布一条空消息。您应该将 mensagem 作为参数传递给函数,然后发布它。
MQTT 客户端循环:
每次检测到人脸时都会调用 client.loop_start() 和 client.loop_stop() 方法,效率不高。相反,在开始时启动一次循环并在程序结束时停止。
这是经过上述更改的代码的修订版本:
# ... [rest of your imports and initializations]
def run(mensagem):
client = connect_mqtt()
publish(client, mensagem)
def publish(client, mensagem):
result = client.publish(topic, mensagem)
# You can check if the publish was successful with result.rc
# Start the MQTT client loop once
client = connect_mqtt()
client.loop_start()
while 1:
ret, img = cap.read()
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
faces = cascata_rosto.detectMultiScale(gray, 1.5, 5)
# ... [rest of your face detection code]
if len(faces) > 0: # If a face is detected
mensagem = "1"
run(mensagem)
else:
mensagem = "0"
run(mensagem)
# ... [rest of your code to display the image]
# Stop the MQTT client loop at the end
client.loop_stop()
cap.release()
cv.destroyAllWindows()
这应该可以帮助您在检测到人脸时向 MQTT 代理发送“1”消息,否则发送“0”消息。确保您的 ESP8266 订阅了正确的主题和代理以接收这些消息。