如何正确使用 OpenCV 和 MQTT 协议?

问题描述 投票:0回答:1

我正在尝试制作一个系统,向我的 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 opencv mqtt face-recognition
1个回答
0
投票

您的 Python 代码似乎大部分已就位,但需要解决一些问题才能使其按预期工作。以下是您需要进行的更改的分步细目:

  1. 人脸检测条件:

    条件 if (cv.rectangle in img == True): 不是检查是否检测到人脸的正确方法。相反,您应该检查面孔列表的长度。

  2. MQTT 发布:

    发布功能当前正在发布一条空消息。您应该将 mensagem 作为参数传递给函数,然后发布它。

  3. 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 订阅了正确的主题和代理以接收这些消息。

© www.soinside.com 2019 - 2024. All rights reserved.