如何将 YOLO 检测从 Python 编写为 Arduino Broad 上的反应式 LED 的脚本

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

我有自己的预训练 YOLO 模型,当我的网络摄像头检测到不同的标签时,我希望 Arduino Uno breadbroad 上的不同颜色的 LED 亮起。

所以,我想首先分配命令让不同的 LED 亮起。 (“G”表示绿色 LED,“R”表示红色 LED,“Y”表示黄色 LED,“A”表示同时打开红色和黄色 LED,“0”表示关闭所有 LED。 ) 我从我的 Arduino 代码开始,如下所示:

char command;

void setup() {
    Serial.begin(9600);
    pinMode(2, OUTPUT);  // Green LED pin
    pinMode(3, OUTPUT);  // Red LED pin
    pinMode(4, OUTPUT);  // Yellow LED pin
}

void loop() {
    if (Serial.available() > 0) {
        command = Serial.read();
        if (command == 'G') {
            // Turn on green LED
            digitalWrite(2, HIGH);
            digitalWrite(3, LOW);  // Turn off red LED
            digitalWrite(4, LOW);  // Turn off yellow LED
        } else if (command == 'R') {
            // Turn on red LED
            digitalWrite(2, LOW);   // Turn off green LED
            digitalWrite(3, HIGH);
            digitalWrite(4, LOW);   // Turn off yellow LED
        } else if (command == 'Y') {
            // Turn on yellow LED
            digitalWrite(2, LOW);   // Turn off green LED
            digitalWrite(3, LOW);   // Turn off red LED
            digitalWrite(4, HIGH);
        } else if (command == 'A') {
            // Turn on both red and yellow LEDs
            digitalWrite(2, LOW);   // Turn off green LED
            digitalWrite(3, HIGH);
            digitalWrite(4, HIGH);
        } else if (command == '0') {
            // Turn off all LEDs
            digitalWrite(2, LOW);
            digitalWrite(3, LOW);
            digitalWrite(4, LOW);
        }
    }
}

在我的 YOLO 模型中,共有三个类

#Classes
names:
  0: aaa
  1: bbb
  2: ccc

因此,对于我的Python代码,我首先打开网络摄像头并加载,然后使用串行库连接到arduino。

from ultralytics import YOLO
import serial
import time
import sys

# Load my YOLO model using
model = YOLO("best.pt")

# Open the serial port for communication with Arduino
arduino = serial.Serial('COM3', 9600)  # Change 'COM3' to your Arduino port

之后,我想用命令给Arduino分配标签,我也尝试做一点

# Map the class labels to corresponding Arduino commands
label_commands = {
    'aaa': 'G',
    'bbb': 'R',
    'ccc': 'Y',
    'aaa_bbb': 'A',
    'aaa_bbb_ccc': 'A',
    'none': '0'
}

while True:
    try:
        results = model.predict(source="0", show=True)  # assumes '0' is your source identifier

        # Extract the detected labels from results
        detected_labels = [item['label'] for item in results.xyxy[0].numpy()]

        # Determine the Arduino command based on detected labels
        if 'aaa' in detected_labels and 'bbb' in detected_labels and 'ccc' in detected_labels:
            command = label_commands['aaa_bbb_ccc']
        elif 'aaa' in detected_labels and 'bbb' in detected_labels:
            command = label_commands['aaa_bbb']
        elif 'aaa' in detected_labels:
            command = label_commands['aaa']
        elif 'bbb' in detected_labels and 'ccc' in detected_labels:
            command = label_commands['aaa_bbb_ccc']
        elif 'bbb' in detected_labels:
            command = label_commands['bbb']
        elif 'ccc' in detected_labels:
            command = label_commands['ccc']
        else:
            command = label_commands['none']

        # Print the command for debugging
        print(f"Sending command to Arduino: {command}")
        sys.stdout.flush()  # Flush the standard output

        # Send the command to Arduino
        arduino.write(command.encode())

    except Exception as e:
        print(f"Error: {e}")
        sys.stdout.flush()  # Flush the standard output

    # Wait for 5 seconds before sending the next command
    time.sleep(5)

但是,这部分代码根本不起作用。我知道我的 arduino 确实已连接,并且我还测试了从 python 随机发送字母命令到 arduino,效果非常好。

此外,当我运行此代码时,运行窗口仅显示以下内容:

1/1: 0... Success ✅ (inf frames of shape 640x480 at 25.00 FPS)


WARNING ⚠️ inference results will accumulate in RAM unless `stream=True` is passed, causing potential out-of-memory
errors for large sources or long-running streams and videos. See https://docs.ultralytics.com/modes/predict/ for help.

Example:
    results = model(source=..., stream=True)  # generator of Results objects
    for r in results:
        boxes = r.boxes  # Boxes object for bbox outputs
        masks = r.masks  # Masks object for segment masks outputs
        probs = r.probs  # Class probabilities for classification outputs

0: 480x640 (no detections), 141.0ms
0: 480x640 1 aaa, 182.2ms
0: 480x640 1 aaa, 134.3ms
0: 480x640 1 aaa, 122.1ms
0: 480x640 (no detections), 121.4ms
0: 480x640 (no detections), 147.5ms
0: 480x640 (no detections), 131.5ms
0: 480x640 (no detections), 140.3ms
0: 480x640 1 aaa, 127.1ms
0: 480x640 1 aaa, 124.1ms
0: 480x640 1 aaa, 123.2ms
0: 480x640 1 aaa, 172.2ms
...

即使使用我的调试脚本,它也没有告诉我正在向 arduino Broad 发送什么命令

        # Print the command for debugging
        print(f"Sending command to Arduino: {command}")
        sys.stdout.flush()  # Flush the standard output
python arduino-uno yolo yolov8
1个回答
0
投票

这些可能是潜在的问题:

  1. 如何从 YOLO 模型的输出中提取标签 - 如果标签未正确提取,命令将不会发送到 Arduino。

  2. 即使 Arduino 已连接并且(如您所述)使用随机命令,但当它在 YOLO 检测循环中完成时,可能会出现通信问题。

然后,当谈到看不到调试输出时,程序本身可能没有到达代码的那部分,或者可能是处理方式不同。

因此,要解决此问题,您需要确保正确提取标签,您可能希望在提取后立即打印这些标签以查看它们是否符合您的预期。我还会简化代码,以便在每次循环迭代中向 Arduino 发送固定命令,而不管 YOLO 输出如何,这样您就可以确认基本循环和串行通信正常工作。另一件事,Arduino 有时需要一些时间来启动和建立串行通信,因此您可能需要调整 Python 脚本以等待 Arduino 被读取,此外,我还会检查更详细的异常,以了解到底在哪里您的代码可能会失败,它会精确定位到问题所在的代码步骤。

因此,这里的代码可能会有所帮助,以便您能够为我们提供帮助,或者您甚至可能能够了解问题出在哪里并解决它:

from ultralytics import YOLO
import serial
import time
import sys

# Load YOLO model
model = YOLO("best.pt")

# Open serial port for Arduino
arduino = serial.Serial('COM3', 9600)
time.sleep(2)  # Wait for Arduino to initialize

# Label commands mapping
label_commands = {
    'aaa': 'G', 'bbb': 'R', 'ccc': 'Y', 'aaa_bbb': 'A', 'aaa_bbb_ccc': 'A', 'none': '0'
}

while True:
    try:
        # Get YOLO predictions
        results = model.predict(source="0")
        detected_labels = [item['label'] for item in results.xyxy[0].numpy()]

        # Determine command
        command = '0'  # Default command
        if 'aaa' in detected_labels:
            command = label_commands['aaa']
        # Add other conditions as required

        # Debugging output
        print(f"Detected Labels: {detected_labels}")
        print(f"Sending command to Arduino: {command}")
        sys.stdout.flush()

        # Send command to Arduino
        arduino.write(command.encode())

    except Exception as e:
        print(f"Error: {e}")
        sys.stdout.flush()

    time.sleep(5)  # Wait before next iteration
© www.soinside.com 2019 - 2024. All rights reserved.