搭建自己的私人家庭相册库:用Python人脸识别,不上传任何云端
你手机里存了几千张照片,想找出所有有家人脸的合影。iCloud 和 Google Photos 都有人脸识别,但你必须把照片传上去。
传上去那一刻,这些照片就不再只属于你了。
有一个方案,全在本地跑,不上传任何数据。一个 Python 脚本,三行命令。下面直接开始。
为什么自己搭
不是什么云方案不好——只是"拍张照片就要经过别人服务器"这件事,值得多一个选项。而且这个选项不需要花钱,只要你有台电脑。
技术方案
核心流程
人脸定位(HOG) → 对齐68个关键点 → 提取128维特征向量 → 欧氏距离比对
三步:
1HOG(方向梯度直方图):把图片分成小格子,算每个格子的明暗变化方向,和训练好的人脸轮廓模板匹配,找到人脸位置。2dlib ResNet:对齐后的人脸送进深度学习网络,输出 128个浮点数,这就是你的"人脸指纹"。3欧氏距离:新照片的128维向量和之前注册的向量算距离,小于0.5判为同一人。技术栈
•face_recognition(dlib 的 Python 封装)存一个人的"人脸指纹"只需要 1.3KB。128 个浮点数。
实操:三步搭起来
第一步:装环境
# macOS 先装 cmake(dlib 编译需要)
brew install cmake
# 安装 face_recognition
pip install face_recognition
# 验证
python3 -c "import face_recognition; print('OK')"
Windows 和 Linux 同样支持。dlib 在 Linux 上编译更快,Windows 建议用 pip 预编译包。
⚠️ macOS ARM64(M芯片)编译 dlib 约 5-10 分钟。
第二步:注册家人人脸
创建一个脚本 family_faces.py,核心两个功能:注册 和 识别。
注册部分:
import face_recognition
import pickle
import os
def register(name, photo_path):
"""注册一张家人照片"""
image = face_recognition.load_image_file(photo_path)
encodings = face_recognition.face_encodings(image)
iflen(encodings) == 0:
print(f"❌ 照片中没有检测到人脸: {photo_path}")
returnFalse
# 128维特征向量
data = {
"encoding": encodings[0],
"source": photo_path
}
# 序列化到文件,仅 1.3KB
with open(f"{name}.pkl", "wb") as f:
pickle.dump(data, f)
print(f"✅ 已注册「{name}」!特征文件: {name}.pkl")
returnTrue
用法:
python3 family_faces.py 注册 "我" /path/to/my_photo.jpg
python3 family_faces.py 注册 "家人" /path/to/family_photo.jpg
对参考照的要求不高——正脸、光线均匀就行。实测一张日常自拍级别的照片就够用。
第三步:识别照片
def check_photo(photo_path, tolerance=0.5):
"""检查一张照片里有哪些已注册的家人"""
import face_recognition
import pickle
import os
# 加载所有已注册的人脸
known = {}
for f in os.listdir("."):
if f.endswith(".pkl"):
name = f[:-4]
with open(f, "rb") as fh:
data = pickle.load(fh)
known[name] = data["encoding"]
# 检测新照片中的人脸
image = face_recognition.load_image_file(photo_path)
face_locations = face_recognition.face_locations(image)
encodings = face_recognition.face_encodings(image, face_locations)
matched = []
for i, encoding inenumerate(encodings):
for name, known_enc in known.items():
matches = face_recognition.compare_faces(
[known_enc], encoding, tolerance=tolerance
)
if matches[0]:
matched.append(name)
break
return matched
用法:
python3 family_faces.py 检查 /path/to/photo.jpg
# 输出:💡 结果: 我、家人
支持一张照片里有多个人——合影也能同时认出每个家人。
批量扫描
如果有一个相册目录:
python3 family_faces.py 扫描 /path/to/相册文件夹/
脚本自动遍历目录下所有 jpg/jpeg/png 图片,输出每张图里有谁:
📂 扫描目录: /path/to/相册文件夹/
已注册家人: 我, 家人
找到 156 张图片
✅ [1/156] 发现我、家人 → family/IMG_001.jpg
[2/156] IMG_002.jpg → 无人脸
[3/156] IMG_003.jpg → 非家人
✅ [4/156] 发现我 → family/IMG_004.jpg
...
效果实测
用一张底图注册,三种不同场景测试:
全部正确,零误报。
dlib 的 ResNet 模型虽然是2017年发布的,日常自拍级别的照片完全够用。一张底图就能覆盖大多数生活场景。
工程要点
阈值调优
tolerance 参数控制匹配严格度:
翻车场景与补救
•戴口罩/大侧脸:dlib 2017年的模型抗遮挡能力一般,可能认不出。补注册一张戴口罩的底图就行。•换发型/长胖了:特征向量变化后可能匹配不上。补注册一张近照,同一人可以有多张底图。•照片太暗/人脸太小:检测阶段就找不到脸。裁剪放大后再试。核心思路不是让算法适应你,而是翻车时补一张底图。每张底图 1.3KB,存一百张也没压力。
文件结构
family-faces/
├── family_faces.py # 主脚本
├── 我.pkl (1.3KB) # "我"的128维人脸向量
├── 家人.pkl (1.3KB) # 家人的128维人脸向量
└── ...
整个目录可以复制到任何电脑、任何操作系统上直接跑。不需要联网、不需要配置、不需要注册账号。
隐私优势
这是这个方案最大的价值:
•照片不离开你的硬盘:所有处理在本地完成,没有任何数据通过网络传输•特征向量不可逆:128个浮点数无法还原成人脸图像,即使文件泄露也无法重建长相•模型开源可审计:dlib 是开源项目,不存在后门或数据采集•物理隔离:把脚本放在不联网的电脑上跑,就是物理级的数据安全
扩展方向
基础版本用顺手了,可以:
1Web UI:加一个简单的 Flask 页面,上传照片自动识别分类2自动归档:扫描后把带家人的照片自动复制到"家人相册"文件夹3定时任务:每周自动扫描新增照片,推送新发现的合影4升级识别模型:换成 InsightFace 的 MobileFaceNet(24MB)或 ArcFace(250MB),抗遮挡和精度更高
完整脚本
完整版 family_faces.py 约 200 行,支持注册、检查单张、批量扫描和列表查看四个子命令。GitHub 上搜索 face_recognition 官方示例就能拼出来,也可以直接复制本文的代码片段。
这个方案不强求你上传、不强求你付费、不强求你联网。它就安静地跑在你的电脑上,帮你从几千张照片里找到家人的脸。
花十分钟搭一个,以后每次翻到合影,至少知道这张照片只属于你自己。
参考工具:face_recognition(dlib封装)、Python 3、pickle
测试环境:macOS ARM64 | 20行 Python 脚本 | 3张测试照全部通过