Python 人脸识别控制 ESP8266 LED 灯实战
本项目演示了如何利用 Python 脚本结合 face_recognition 库实现本地人脸检测,并通过 HTTP 协议控制 ESP8266 模块上的 LED 灯。相比直接刷入固件,这种方式更便于在 PC 端进行复杂的图像处理与逻辑调试。
环境准备
核心依赖是 face_recognition 库,它封装了 dlib 等底层算法。安装前请注意以下事项:
pip install face_recognition
如果在 Windows 下遇到编译错误(提示需要 Visual Studio C++ 构建工具),通常是因为缺少 dlib 的预编译包。建议先手动下载并安装 dlib 的 wheel 包,或者安装 Visual Studio Build Tools 后再重试。
核心逻辑说明
代码主要包含三个部分:
- 人脸加载:从指定目录读取图片,提取特征编码并缓存到内存中,避免重复计算。
- 实时检测:调用摄像头获取视频流,缩小图像尺寸以提升处理速度,再与已知编码比对。
- 硬件控制:匹配成功后发送 HTTP 请求开启 LED,并利用线程设置延时关闭,防止频繁触发。
这里特别加入了冷却时间(cooldown)机制,避免同一张脸连续触发导致 LED 状态混乱。
完整代码实现
将已知人脸图片放入 known_faces 文件夹后,运行以下脚本即可。
import requests
import cv2
import face_recognition
import os
import time
import threading
# ESP8266 的 IP 地址配置
ESP8266_IP = "192.168.1.12"
BASE_URL = f"http://{ESP8266_IP}"
TEST_URL = f"{BASE_URL}/text/plain"
LED_ON_URL = f"{BASE_URL}/led/on"
LED_OFF_URL = f"{BASE_URL}/led/off"
class FaceRecognitionSystem:
def __init__(self):
"""初始化人脸识别系统"""
self.known_faces_dir = r"D:\PythonProject\known_faces" # 图片存放地址
self.known_face_encodings = []
self.known_face_names = []
.last_trigger_time =
.led_cooldown =
.led_is_on =
.load_known_faces()
():
os.path.exists(.known_faces_dir):
()
all_files = os.listdir(.known_faces_dir)
filename all_files:
filename.lower().endswith((, , )):
image_path = os.path.join(.known_faces_dir, filename)
()
:
image = face_recognition.load_image_file(image_path)
Exception e:
()
face_encodings = face_recognition.face_encodings(image)
(face_encodings) > :
.known_face_encodings.append(face_encodings[])
.known_face_names.append(os.path.splitext(filename)[])
()
:
()
:
()
()
():
.known_face_encodings:
small_frame = cv2.resize(frame, (, ), fx=, fy=)
rgb_small_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)
face_locations = face_recognition.face_locations(rgb_small_frame)
face_locations:
face_encodings = face_recognition.face_encodings(
rgb_small_frame, face_locations
)
face_encoding face_encodings:
matches = face_recognition.compare_faces(
.known_face_encodings, face_encoding, tolerance=
)
matches:
()
:
()
():
current_time = time.time()
should_turn_on .led_is_on:
current_time - .last_trigger_time >= .led_cooldown:
()
response = requests.get(LED_ON_URL, timeout=)
response.status_code == :
()
.led_is_on =
.last_trigger_time = current_time
():
time.sleep()
response = requests.get(LED_OFF_URL, timeout=)
response.status_code == :
()
.led_is_on =
timer = threading.Thread(target=turn_off_led)
timer.daemon =
timer.start()
:
()
():
()
:
response = requests.get(, timeout=)
response.status_code == :
()
:
()
():
test_esp8266_connection():
()
face_system = FaceRecognitionSystem()
face_system.known_face_encodings:
()
()
cap = cv2.VideoCapture()
cap.isOpened():
()
()
:
:
ret, frame = cap.read()
ret:
()
face_detected = face_system.recognize_faces(frame)
face_system.control_led(face_detected)
status_text = face_detected
color = (, , ) face_detected (, , )
cv2.putText(frame, , (, ),
cv2.FONT_HERSHEY_SIMPLEX, , color, )
cv2.putText(frame, face_system.led_is_on ,
(, ), cv2.FONT_HERSHEY_SIMPLEX, ,
(, , ) face_system.led_is_on (, , ), )
cv2.putText(frame, , (, frame.shape[]-),
cv2.FONT_HERSHEY_SIMPLEX, , (, , ), )
cv2.imshow(, frame)
cv2.waitKey() & == ():
time.sleep()
Exception e:
()
:
cap.release()
cv2.destroyAllWindows()
:
face_system.led_is_on:
requests.get(LED_OFF_URL, timeout=)
()
:
()
__name__ == :
main()

