查看: 151|回复: 1

[聊技术] 大佬们为啥我这个代码得出的置信度0.9几啊我每个类别弄了5个图片

[复制链接]

8

主题

16

回帖

53

积分

一年会员

Rank: 2

积分
53
发表于 2025-4-17 08:07:01 | 显示全部楼层 |阅读模式
# main.py
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.responses import JSONResponse
import face_recognition  # 人脸识别核心库
import numpy as np  # 数值计算
from pathlib import Path  # 路径处理
from PIL import Image  # 图像验证
import io  # 二进制流处理
# 初始化FastAPI应用
app = FastAPI(title="人脸识别服务", description="基于FastAPI和face_recognition的人脸识别API")
# ----------------------------
# 本地人脸库初始化模块
# ----------------------------
def load_known_faces(faces_dir="faces"):
"""
加载本地人脸库并提取特征编码
Args:
faces_dir (str): 人脸库目录路径,默认"faces"
Returns:
dict: {人物名称: [特征编码列表]}
"""
known_faces = {}
try:
# 遍历faces目录下的所有子目录(每个人物一个目录)
for person_dir in Path(faces_dir).iterdir():
if person_dir.is_dir():
name = person_dir.name  # 目录名作为人物名称
encodings = []
# 遍历该人物的所有图片
for image_path in person_dir.glob("*"):
try:
# 加载图片并提取人脸特征
image = face_recognition.load_image_file(image_path)
face_locations = face_recognition.face_locations(image)
face_encs = face_recognition.face_encodings(image,face_locations,num_jitters=8)
if face_encs:
enc=face_encs[0]
enc_normalized=enc/np.linalg.norm(enc)#新增标准化
encodings.append(enc_normalized)
else:
print(f"[WARN] {image_path} 未检测到人脸,已跳过")
except Exception as e:
print(f"[ERROR] 加载 {image_path} 失败: {str(e)}")
# 保存该人物的所有特征编码
if encodings:
known_faces[name] = encodings
else:
print(f"[WARN] 人物 {name} 无有效图片,已跳过")
print(f"[INFO] 人脸库加载完成,已注册 {len(known_faces)} 人")
return known_faces
except FileNotFoundError:
raise RuntimeError(f"人脸库目录 {faces_dir} 不存在!")
# 全局加载已知人脸库
known_faces = load_known_faces()
# ----------------------------
# API接口实现
# ----------------------------
@app.post("/api/recognize")
async def recognize_face(image: UploadFile = File(...)):
"""
人脸识别接口
- 支持单张图片上传
- 返回检测到的人脸位置、名称和置信度
"""
# ----------------------------
# 1. 文件验证阶段
# ----------------------------
# 验证文件类型
if image.content_type not in ["image/jpeg", "image/png"]:
return JSONResponse(
status_code=400,
content={"success": False, "message": "仅支持JPG/PNG格式"}
)
# 验证文件内容
try:
contents = await image.read()
img = Image.open(io.BytesIO(contents))
img.verify()  # 校验图片完整性
image_stream = io.BytesIO(contents)  # 重置流指针
except Exception as e:
return JSONResponse(
status_code=400,
content={"success": False, "message": "无效的图像文件"}
)
# ----------------------------
# 2. 人脸处理阶段
# ----------------------------
try:
# 将图片转换为numpy数组
image_np = face_recognition.load_image_file(image_stream)
# 检测所有人脸位置(格式:top, right, bottom, left)
face_locations = face_recognition.face_locations(image_np)
if not face_locations:
return JSONResponse(
content={"success": True, "faces": [], "message": "未检测到人脸"}
)
# 提取所有人脸特征编码
face_encodings = face_recognition.face_encodings(image_np, face_locations,num_jitters=8)
# ----------------------------
# 3. 人脸比对逻辑
# ----------------------------
faces_result = []
for i, (face_encoding, location) in enumerate(zip(face_encodings, face_locations)):
max_similarity = -1
best_name = "unknown"
second_similarity=-1#新增:记录次高相似度
# 与本地人脸库逐一比对
for name, encodings in known_faces.items():
for enc in encodings:
#标准化当前检测的人脸特征
face_encoding_normalized=face_encoding/np.linalg.norm(face_encoding)
#标准化已知人脸特征
enc_normalized=enc/np.linalg.norm(enc)
similarity=np.dot(face_encoding_normalized,enc_normalized)
if similarity>max_similarity:
second_similarity=max_similarity
max_similarity=similarity
best_name=name
elif similarity>second_similarity:
second_similarity=similarity
# 置信度计算(将相似度映射到[0,1])
if max_similarity>second_similarity+0.1:
confidence = round((max_similarity + 1) / 2, 2)
else:
best_name="unknown"
confidence=0.0
# 设置阈值(0.7对应置信度0.85)
if max_similarity < 0.7:
best_name = "unknown"
confidence = 0.0
# 记录人脸信息
face_info = {
"location": list(location),  # 转换为列表格式
"name": best_name,
"confidence": confidence,
"max_similarity":max_similarity,
"second_similarity":second_similarity
}
faces_result.append(face_info)
# ----------------------------
# 4. 返回最终结果
# ----------------------------
return JSONResponse(
content={
"success": True,
"faces": faces_result,
"message": f"检测到 {len(faces_result)} 张人脸"
}
)
except Exception as e:
# 捕获未处理的异常
return JSONResponse(
status_code=500,
content={"success": False, "message": f"服务器内部错误: {str(e)}"}
)
# ----------------------------
# 服务启动指令
# ----------------------------
if __name__ == "__main__":
import uvicorn
uvicorn.run(app="Cv:app", host="127.0.0.1", port=8000, reload=True)
回复

使用道具 举报

2

主题

22

回帖

45

积分

一年会员

Rank: 2

积分
45
发表于 2025-4-17 08:40:05 来自手机 | 显示全部楼层
嗯哼,嗯哼,姐也坐回沙发。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

特惠

限量优惠活动

正在火热进行

站长

添加站长微信

领取运营礼包

下载

便携运营智库

立即下载APP

工具

运营工具导航

AI工具导航

帮助

帮助中心

常见问题

顶部