开发工具 智能门铃项目实战:人脸识别 + 微信推送,家门口的小管家
智能门铃项目实战:人脸识别 + 微信推送,家门口的小管家
**快递到了不知道?陌生人按门铃不敢开?这个 DIY 智能门铃帮你盯着家门口! 上周我家门口被塞了好几张传单,等我下班回来才发现。当时就想:要是有个东西能自动识别门口的人,还能通知我就好了。于是这个周末,我动手做了个智能门铃——不仅能人脸识别,还能通过微信推送消息到手机。
整个项目成本不到 300 块,用树莓派 + 摄像头 + 微信推送服务就能搞定。今天把完整过程分享给大家。
需要准备什么?
| 物品 | 型号/规格 | 价格 |
|---|---|---|
| 树莓派 | Raspberry Pi 4B 2GB | ¥280 |
| 摄像头 | USB 摄像头 1080P | ¥35 |
| 麦克风 | USB 麦克风(可选) | ¥25 |
| 门铃按钮 | 常开自复位开关 | ¥8 |
| 杜邦线 | 公对母 20cm | ¥5 |
| 外壳 | 3D 打印/塑料盒 | ¥20 |
| 总计** | ¥373 |
如果你已经有树莓派,成本可以压到 100 块以内。摄像头我用的是普通的 USB webcam,淘宝随便买的,能看清人脸就行。
步骤 1:系统环境搭建
首先给树莓派装上系统。我推荐用 Raspberry Pi OS(64 位),下载地址:https://www.raspberrypi.com/software/operating-systems/
烧录好系统后,通过 SSH 登录树莓派,然后安装必要的依赖:
# 更新系统
sudo apt-get update
sudo apt-get upgrade -y
# 安装 Python 依赖
sudo apt-get install -y python3-pip python3-opencv python3-numpy
sudo apt-get install -y libatlas-base-dev libjasper-dev libqtgui4 libqt4-test
# 安装 face_recognition 库(基于 dlib)
pip3 install face_recognition
pip3 install requests
pip3 install gpiozero
注意事项: ⚠️ face_recognition 库编译比较慢,树莓派上可能需要 20-30 分钟。建议先喝杯咖啡,让它发热吧,别发光就好。
如果编译过程中报错,通常是缺少 C++ 编译器,执行下面命令:
sudo apt-get install -y build-essential cmake
步骤 2:录入家庭成员人脸
接下来要录入家里人的人脸数据。我写了一个简单的脚本,调用摄像头拍照并提取人脸特征:
# enroll_face.py
import cv2
import face_recognition
import pickle
import os
def enroll_face(name, num_photos=5):**
"""录入人脸,拍摄多张照片取平均特征"""
print(f"开始录入 {name} 的人脸,请保持表情自然...")
encodings = []
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("❌ 摄像头无法打开,请检查连接")
return False
for i in range(num_photos):
ret, frame = cap.read()
if not ret:
continue
# 转 RGB 格式
rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 检测人脸
face_locations = face_recognition.face_locations(rgb_frame)
if len(face_locations) == 0:
print(f"第{i+1}张:未检测到人脸,请正对摄像头")
continue
if len(face_locations) > 1:
print(f"第{i+1}张:检测到多张人脸,请确保只有一人")
continue
# 提取人脸特征
face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
if face_encodings:
encodings.append(face_encodings[0])
print(f"第{i+1}张:✅ 特征提取成功")
cap.release()
if not encodings:
print("❌ 未能提取到任何人脸特征")
return False
# 保存特征(取平均)
avg_encoding =
# 加载或创建数据库
db_file = "face_database.pkl"
if os.path.exists(db_file):
with open(db_file, "rb") as f:
database = pickle.load(f)
else:
database = {}
database = avg_encoding
with open(db_file, "wb") as f:
pickle.dump(database, f)
print(f"✅ {name} 的人脸录入成功!共{len(encodings)}张有效照片")
return True
if __name__ == "__main__":
name = input("请输入姓名:")
enroll_face(name)
运行脚本:
python3 enroll_face.py
按提示输入家人姓名,然后对着摄像头拍几张照片。建议每人录入 5 张以上,识别准确率会更高。
步骤 3:微信推送服务配置
这里用 Server 酱(https://sct.ftqq.com/)实现微信推送,免费且简单:
-
访问 Server 酱官网,用微信扫码登录
-
绑定微信后,获取 SendKey(类似:
SCT123456abcdef) -
在微信关注”方糖”公众号,就能收到推送
测试推送:
# 替换为你的 SendKey
curl -X POST "https://sctapi.ftqq.com/SCT123456abcdef.send" \
-d "text=门铃测试" \
-d "desp=有人在门口按门铃了!"
如果微信收到消息,说明配置成功。
步骤 4:主程序编写
重头戏来了!下面是完整的主程序,集成了人脸检测和微信推送:
# smart_doorbell.py
import cv2
import face_recognition
import pickle
import requests
import time
from gpiozero import Button
from datetime import datetime
# ============ 配置区 ============
SERVERCHAN_KEY = "SCT123456abcdef" # 替换为你的 SendKey
FACE_DATABASE = "face_database.pkl"
BUTTON_PIN = 17 # GPIO 17 接门铃按钮
CAMERA_INDEX = 0
RECOGNITION_THRESHOLD = 0.6 # 人脸识别阈值
# ===============================
def load_face_database():
"""加载人脸数据库"""
if not os.path.exists(FACE_DATABASE):
print("❌ 人脸数据库不存在,请先运行 enroll_face.py")
return {}, []
with open(FACE_DATABASE, "rb") as f:
database = pickle.load(f)
names = list(database.keys())
encodings = list(database.values())
print(f"✅ 已加载 {len(names)} 个人脸:{', '.join(names)}")
return names, encodings
def send_wechat_push(title, content, image_path=None):
"""发送微信推送"""
url = f"https://sctapi.ftqq.com/{SERVERCHAN_KEY}.send"
data = {
"text": title,
"desp": content
}
# 如果有图片,上传到图床后附加
if image_path and os.path.exists(image_path):
# Server 酱支持图片 URL,这里简化处理
pass
try:
response = requests.post(url, data=data, timeout=10)
if response.status_code == 200:
print("✅ 微信推送成功")
return True
else:
print(f"❌ 推送失败:{response.text}")
return False
except Exception as e:
print(f"❌ 推送异常:{e}")
return False
def recognize_face(frame, known_names, known_encodings):
"""识别人脸"""
# 缩小图片加速处理
small_frame = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)
rgb_frame = cv2.cvtColor(small_frame, cv2.COLOR_BGR2RGB)
# 检测人脸
face_locations = face_recognition.face_locations(rgb_frame)
if not face_locations:
return None, "未检测到人脸"
# 提取特征
face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
if not face_encodings:
return None, "无法提取人脸特征"
# 匹配已知人脸
face_encoding = face_encodings[0]
matches = face_recognition.compare_faces(known_encodings, face_encoding, RECOGNITION_THRESHOLD)
face_distances = face_recognition.face_distance(known_encodings, face_encoding)
if len(face_distances) > 0:
best_match_idx = np.argmin(face_distances)
if matches:
name = known_names
confidence = 1 - face_distances
return name, f"识别成功:{name} (置信度:{confidence:.2%})"
return "陌生人", "⚠️ 检测到陌生人"
def capture_and_save():
"""抓拍并保存图片"""
cap = cv2.VideoCapture(CAMERA_INDEX)
ret, frame = cap.read()
cap.release()
if ret:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"captures/{timestamp}.jpg"
os.makedirs("captures", exist_ok=True)
cv2.imwrite(filename, frame)
return filename
return None
def main():
print("🔔 智能门铃启动中...")
# 加载人脸库
known_names, known_encodings = load_face_database()
if not known_names:
return
# 初始化门铃按钮
doorbell_button = Button(BUTTON_PIN, pull_up=False)
print("✅ 门铃系统就绪,等待按铃...")
last_push_time = 0
PUSH_COOLDOWN = 30 # 30 秒防抖
while True:
if doorbell_button.is_pressed:
current_time = time.time()
# 防抖处理
if current_time - last_push_time > /var/log/doorbell.log 2>&1
重启测试:
sudo reboot
重启后检查日志:
tail -f /var/log/doorbell.log
常见问题排查
问题 1:** 人脸识别很慢,要 3-4 秒才响应**
- 原因:** 树莓派 CPU 性能有限,face_recognition 库计算量大**
- 解决:** **
-
缩小输入图片分辨率(代码中已处理)
-
改用 USB 加速棒(如 Intel Neural Compute Stick)
-
或者降低识别频率,改为定时检测
-
问题 2:** 摄像头画面太暗,晚上看不清**
- 原因:** 普通摄像头没有红外夜视**
- 解决:** **
-
加装红外补光灯(¥15 左右)
-
换带夜视功能的摄像头(¥60-80)
-
调整摄像头曝光参数
-
问题 3:** 微信推送延迟高**
- 原因:** Server 酱服务器响应慢**
- 解决:** **
-
检查网络连接
-
改用其他推送服务(如 Bark、PushPlus)
-
本地搭建 MQTT 服务,用 Home Assistant 推送
-
问题 4:** 误识别率高,经常认错人**
- 原因:** 录入照片太少或光线变化大**
- 解决:** **
-
每人录入 10 张以上照片(不同光线/角度)
-
调低识别阈值(代码中 RECOGNITION_THRESHOLD)
-
定期更新人脸库
-
扩展玩法
这个基础版本还能继续升级:
- 语音对讲**:加装麦克风和喇叭,实现双向通话**
- 远程开门**:接继电器控制电锁,微信回复”开门”即可**
- 视频录像**:检测到陌生人自动录像保存**
- 接入 Home Assistant**:联动其他智能家居设备**
- 多人识别**:区分快递员、家人、访客,推送不同消息
总结
这个智能门铃项目用了不到一天就完成了,核心就是三点:**
-
用
face_recognition库做人脸识别 -
用 Server 酱实现微信推送
-
用 GPIO 检测门铃按钮
成本可控,效果也不错。识别准确率大概 90% 左右,家里人基本都能认出来。陌生人会触发特别提醒,安全感满满。
如果你也想做一个,遇到问题欢迎在评论区留言。代码我已经放到 GitHub 上了,欢迎 Star:https://github.com/makeronsite/smart-doorbell
希望这篇博客文章对您有所帮助!
相关资源:**