You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

人脸识别Arduino-Python串口联动LED功能异常求助

人脸检测门禁灯控功能修复

问题描述

需要实现:检测到已注册人脸时点亮绿灯(允许通行);检测到未注册人脸时点亮红灯。当前Python与Arduino代码无法正常实现该功能,以下是问题排查与修正方案。

原代码问题分析

Python代码问题

  1. 缺少依赖导入:代码中使用cv2库但未导入,直接运行会报错
  2. 逻辑顺序错误:检测到人脸后先发送绿灯指令(b'o'),还没完成人脸匹配就触发绿灯,不符合需求
  3. 未处理未注册人脸场景:仅处理了“检测到人脸”和“匹配到注册人脸”的情况,未匹配时无对应指令触发红灯
  4. 串口无初始化校验:未确认串口是否成功打开,可能导致通信失败

Arduino代码问题

  1. 未读取串口数据:while(Serial.available())循环内未将串口数据读取到var变量,导致指令判断永远基于初始值,无法响应Python发送的指令
  2. 指令与灯控逻辑反向:原代码中'o'对应绿灯、'f'对应红灯,与需求中“匹配到人脸亮绿灯”的逻辑完全相反
  3. 无默认状态维护:未处理无串口指令时的灯状态,可能出现灯态混乱

修正后的代码

Python代码

import face_recognition as fr
import os
import serial
import cv2  # 补充缺失的OpenCV库导入

# 初始化串口,添加缓存清空与超时设置确保连接稳定
porta_serial = serial.Serial('COM3', 9600, timeout=1)
porta_serial.flush()

encoders = []
nomes = []

def criarEncoders():
    lista = os.listdir('Pessoas')
    for arquivo in lista:
        imAtual = fr.load_image_file(f'Pessoas/{arquivo}')
        imAtual = cv2.cvtColor(imAtual, cv2.COLOR_BGR2RGB)
        # 增加异常处理,避免单张图片无人脸导致程序崩溃
        try:
            encoders.append(fr.face_encodings(imAtual)[0])
            nomes.append(os.path.splitext(arquivo)[0])
        except IndexError:
            print(f"警告:{arquivo}中未检测到人脸,已跳过")

def compararWebcam():
    video = cv2.VideoCapture(0)
    face_matched = False

    while True:
        check, img = video.read()
        if not check:
            print("无法读取摄像头画面")
            break
        
        imgP = cv2.resize(img, (0, 0), None, 0.25, 0.25)
        imgP = cv2.cvtColor(imgP, cv2.COLOR_BGR2RGB)

        faceLoc = fr.face_locations(imgP)
        face_matched = False
        matched_name = ""

        if faceLoc:
            # 绘制人脸框
            y1, x2, y2, x1 = faceLoc[0]
            y1, x2, y2, x1 = y1*4, x2*4, y2*4, x1*4
            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
            
            encodeImg = fr.face_encodings(imgP)[0]
            # 遍历比对注册人脸库
            for id, enc in enumerate(encoders):
                comp = fr.compare_faces([encodeImg], enc)
                if comp[0]:
                    face_matched = True
                    matched_name = nomes[id]
                    cv2.rectangle(img, (x1, y2-35), (x2, y2), (0, 255, 0), -1)
                    cv2.putText(img, matched_name, (x1+6, y2-6), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255, 255), 2)
                    print(matched_name)
                    break
            
            # 根据匹配结果发送对应指令
            if face_matched:
                porta_serial.write(b'f')  # 匹配成功,发送绿灯指令
            else:
                porta_serial.write(b'o')  # 未匹配,发送红灯指令
        else:
            # 未检测到人脸,发送默认红灯指令
            porta_serial.write(b'q')

        cv2.imshow('Webcam', img)
        # 按下q键退出程序
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    video.release()
    cv2.destroyAllWindows()
    porta_serial.close()  # 退出时关闭串口

criarEncoders()
compararWebcam()

Arduino代码

int led_liberado = 8;  // 绿灯:对应已注册人脸
int led_nao_liberado = 7;  // 红灯:对应未注册/无人脸
char var;

void setup() {
  Serial.begin(9600);
  pinMode(led_liberado, OUTPUT);
  pinMode(led_nao_liberado, OUTPUT);
  // 初始状态:红灯亮,绿灯灭
  digitalWrite(led_nao_liberado, HIGH);
  digitalWrite(led_liberado, LOW);
}

void loop() {
  if (Serial.available() > 0) {
    var = Serial.read();  // 读取串口数据到变量
    if (var == 'f') {
      // 匹配到注册人脸:绿灯亮,红灯灭
      digitalWrite(led_liberado, HIGH);
      digitalWrite(led_nao_liberado, LOW);
    } else if (var == 'o') {
      // 检测到未注册人脸:红灯亮,绿灯灭
      digitalWrite(led_nao_liberado, HIGH);
      digitalWrite(led_liberado, LOW);
    } else if (var == 'q') {
      // 未检测到人脸:回到初始红灯状态
      digitalWrite(led_nao_liberado, HIGH);
      digitalWrite(led_liberado, LOW);
    }
  }
}

额外注意事项

  1. 确保Pessoas文件夹下的图片均为单人脸清晰照片,避免人脸编码失败
  2. 确认Arduino的COM口与Python代码中的COM3一致(可在Arduino IDE的工具菜单查看)
  3. 运行Python代码前,先上传Arduino代码并关闭串口监视器,避免端口占用冲突

内容的提问来源于stack exchange,提问作者Iago Molina Camargo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 02:01:29