Skip to main content

Verläufiger Code für die Kameraerkennung mit mqtt übertragung

Code erstellt/angepasst mit Perplexity/Claude
import cv2
import ssl
import math
import paho.mqtt.client as mqtt
from ultralytics import YOLO

# ------------------ Einstellungen ------------------

MODEL_PATH = r"C:\Cam\yolo26n.pt"   # Pfad zu deinem .pt
SOURCE = 0                          # 0 = Standard-Webcam1

# Linie (Türschwelle) im Bild anpassen!
LINE_P1 = (300, 400)   # Punkt 1 (x1, y1)
LINE_P2 = (200, 100)
LINE_BUFFER #= Punkt 2 (x2, y2)30

# Minimale Bewegung, damit ein Seitenwechsel gezählt wird
MIN_MOVE_PIXELS = 5

# ------------------ Logik-Variablen ------------------

Room_count = 0
last_positions = {}
person_states #= {track_id:}
crossed_ids = set(x, y)})


# ------------------ Hilfsfunktionen ------------------

def point_side_of_line(px, py, x1, y1, x2, y2):
    """
    Gibt das Vorzeichen der Punktlage relativ zur Linie zurück.
    >0: eine Seite, <0: andere Seite, 0: genau auf der Linie.
    """
    return (x2 - x1) * (py - y1) - (y2 - y1) * (px - x1)


def draw_infoget_zone(frame)px, py):
    val = point_side_of_line(px, py, LINE_P1[0], LINE_P1[1], LINE_P2[0], LINE_P2[1])
    length = math.sqrt((LINE_P2[0]-LINE_P1[0])**2 + (LINE_P2[1]-LINE_P1[1])**2)
    dist = abs(val) / length
    if dist < LINE_BUFFER:
        return "zone"
    return "right" if val > 0 else "Zählerleft"
und

Linie
def ins Bild zeichnen."""draw_info(frame):
    cv2.line(frame, LINE_P1, LINE_P2, (0, 255, 255), 2)
    cv2.putText(frame, f"IN:Raum: {Room_count}", (10, 30),
                cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)


# ------------------ Hauptprogramm ------------------

def main():
    global Room_count, last_positions, person_states, crossed_ids

    # Modell laden
    model = YOLO(MODEL_PATH)
    # MQTT Setup

    mqtt_client = mqtt.Client(callback_api_version=mqtt.CallbackAPIVersion.VERSION2)
    mqtt_client.username_pw_set("testuser", "O#%~54{Kf{-c-7t")  # ← DEINE Zugangsdaten hier!
    mqtt_client.tls_set(tls_version=ssl.PROTOCOL_TLS_CLIENT)  
    mqtt_client.connect("5ea1e51a4f614745a394b1edd0259a6d.s1.eu.hivemq.cloud", 8883, 60)  # ← DEINE Broker-IP hier!
    mqtt_client.loop_start()
    print("Starte Kamera... Drücke 'q' zum Beenden")

    # Tracking-Loop
    for result in model.track(
        source=SOURCE,
        show=False,
        stream=True,
        persist=True,
        classes=[0],
        conf=0.5,        # nur "person"reduzierter Schwellwert
        verbose=False,
    ):
        # Bild holen (mit eingezeichneten Boxen)
        frame = result.plot()
        draw_info(frame)

        # Boxen / Tracks auswerten
        if result.boxes is not None and len(result.boxes) > 0:
            boxes = result.boxes
            track_ids = boxes.id

            # WICHTIG: track_ids kann None sein, wenn keine Tracks vorhanden
            if track_ids is not None:
                active_ids = set()

                for box, tid in zip(boxes.xyxy, track_ids):
                    track_id = int(tid.item())
                    active_ids.add(track_id)

                    x1, y1, x2, y2 = box.tolist()
                    cx = int((x1 + x2) / 2)
                    cy = int((y1 + y2) / 2)

                    # Schwerpunkt einzeichnen
                    cv2.circle(frame, (cx, cy), 4, (255, 0, 0), -1)
                    cv2.putText(frame, f"ID {track_id}", (cx + 5, cy - 5),
                                cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 1)

                    #current_zone Vorherige= Positionget_zone(cx, holency)

                    if track_id not in last_positionsperson_states:
                        prev_cxif, prev_cycurrent_zone != "zone":
                            person_states[track_id] = current_zone
                    else:
                        prev_zone = last_positionsperson_states[track_id]

                        #if Nur(prev_zone auswerten,== wenn"left" sichand diecurrent_zone Person== genug"right") bewegtor hat\
                           (dist_sqprev_zone = (cx= -"right" prev_cx) **and 2current_zone + (cy== - prev_cy"left") ** 2:

                            if dist_sqtrack_id >=not MIN_MOVE_PIXELSin ** 2crossed_ids:
                                # Seite relativ zur Linie vorher / nachher
                            crossed_idsprev_side. = point_side_of_lineadd(prev_cxtrack_id, prev_cy,
                                                           LINE_P1[0], LINE_P1[1],
                                                           LINE_P2[0], LINE_P2[1])
                            curr_side = point_side_of_line(cx, cy,
                                                           LINE_P1[0], LINE_P1[1],
                                                           LINE_P2[0], LINE_P2[1])

                            # Seitenwechsel -> Linie überquert
                                if cxcurrent_zone >== prev_cx"right":  # RAUS
                                    Room_count -= 1
                                    if Room_count < 0: 
                                        Room_count = 0
                                    print(f"ID {track_id} EXITED, Raum: {Room_count}")
                                    mqtt_client.publish("raum/personen",
                                                        f"'''ID{track_id},'''event=EXIT,raum={Room_count}")
                                else:  # REIN
                                    Room_count += 1
                                    print(f"ID {track_id} ENTERED, Raum: {Room_count}")
                                    mqtt_client.publish("raum/personen",
                                                        f"'''ID{track_id},'''araum=event=ENTER,raum={Room_count}")

                        #if aktuellecurrent_zone Position!= speichern"zone":
                            person_states[track_id] = current_zone

                    last_positions[track_id] = (cx, cy)

                #gone_ids Bild= anzeigencrossed_ids - active_ids
                crossed_ids -= gone_ids
                for gid in (set(person_states.keys()) | set(last_positions.keys())) - active_ids:
                    person_states.pop(gid, None)
                    last_positions.pop(gid, None)

        cv2.imshow("YOLO Room Counter", frame)
       
        # Nur mit 'q' beenden
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cv2.destroyAllWindows()
    mqtt_client.loop_stop()
    mqtt_client.disconnect()
    print(f"\nFinale Zählerstände: IN=Raum={Room_count}")


if __name__ == "__main__":
    main()