You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无法实现人脸识别控制Arduino LED功能,寻求代码调试方案

解决人脸识别触发Arduino LED的问题

我看你已经搭好了基础框架,但在检测到人脸时发送信号给Arduino的核心逻辑还没补上,而且还有几个容易踩的坑需要注意,我来帮你完善并梳理清楚:

你的核心需求复盘

  • 用OpenCV实时检测摄像头中的人脸
  • 当**检测到人脸(出现识别框)**时向Arduino发送1点亮LED;未检测到则发送0熄灭LED

现有代码的核心缺失

你提供的代码只完成了初始化部分,缺少人脸检测后的状态判断逻辑,以及串口发送信号的关键代码块,同时也没考虑Arduino端的接收逻辑(这部分必须配套!)


完善后的Python代码(电脑端)

import cv2
import sys
import serial
from time import sleep

# 初始化人脸分类器(如果没传命令行参数,默认用当前目录的人脸分类器文件)
cascPath = sys.argv[1] if len(sys.argv) > 1 else "haarcascade_frontalface_default.xml"
faceCascade = cv2.CascadeClassifier(cascPath)

# 初始化串口连接(Windows用户请改为COM3/COM4这类端口,需根据实际设备调整)
try:
    ser = serial.Serial('/dev/ttyACM0', 9600, timeout=1)
    sleep(2)  # 关键:给Arduino上电重启的时间,否则会错过初始信号
    print("串口连接成功")
except serial.SerialException as e:
    print(f"串口连接失败: {e}")
    sys.exit(1)

# 初始化摄像头
video_capture = cv2.VideoCapture(0)
# 记录上一次的状态,避免重复发送相同信号(减少串口冗余)
last_state = None

while True:
    # 捕获一帧图像
    ret, frame = video_capture.read()
    if not ret:
        print("无法获取摄像头画面")
        break

    # 转为灰度图(人脸检测算法需要灰度图输入)
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # 执行人脸检测
    faces = faceCascade.detectMultiScale(
        gray,
        scaleFactor=1.1,
        minNeighbors=5,
        minSize=(30, 30),
        flags=cv2.CASCADE_SCALE_IMAGE
    )

    # 判断当前状态并发送信号
    current_state = 1 if len(faces) > 0 else 0
    # 只有状态变化时才发送信号,避免串口频繁通信
    if current_state != last_state:
        ser.write(str(current_state).encode('utf-8'))
        print(f"发送信号: {current_state}")
        last_state = current_state

    # 在画面上绘制人脸识别框
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)

    # 显示实时画面
    cv2.imshow('Face Detection', frame)

    # 按Q键退出程序
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 程序结束后清理资源
video_capture.release()
cv2.destroyAllWindows()
ser.close()

配套的Arduino代码(硬件端)

电脑发了信号,Arduino也要能接收并执行动作,这部分代码不能少:

const int ledPin = 13; // 用板载LED测试,也可以外接其他引脚
int receivedSignal = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600); // 波特率要和Python端一致
  digitalWrite(ledPin, LOW); // 初始状态熄灭LED
}

void loop() {
  if (Serial.available() > 0) {
    // 把串口收到的字符转成数字
    receivedSignal = Serial.read() - '0';
    if (receivedSignal == 1) {
      digitalWrite(ledPin, HIGH);
    } else {
      digitalWrite(ledPin, LOW);
    }
  }
}

关键注意事项

  • 串口端口适配:Windows用户要在设备管理器里查看Arduino对应的COM端口,Mac/Linux用户可以用ls /dev/tty.*命令查看,替换代码中的端口路径
  • 权限问题:Linux/Mac用户可能需要给串口权限,执行sudo chmod 666 /dev/ttyACM0(替换成你的端口)
  • 人脸分类器文件:如果找不到haarcascade_frontalface_default.xml,可以从OpenCV的安装目录中复制,或者直接在当前目录下载这个文件
  • 避免信号刷屏:加入last_state变量是为了防止每次循环都发相同信号,减少串口通信压力

内容的提问来源于stack exchange,提问作者Dixon

火山引擎 最新活动