360 lines
9.3 KiB
Markdown
360 lines
9.3 KiB
Markdown
|
|
# 人脸特征提取模块 API 文档
|
|||
|
|
|
|||
|
|
## 概述
|
|||
|
|
|
|||
|
|
`face_feature_extractor.py` 是一个独立的人脸特征提取模块,输入图像,输出质量评估合格的特征值。
|
|||
|
|
|
|||
|
|
### 主要功能
|
|||
|
|
- ✅ 人脸检测和关键点检测
|
|||
|
|
- ✅ 人脸对齐和预处理
|
|||
|
|
- ✅ 多维度质量评估(亮度、清晰度、姿态、分辨率)
|
|||
|
|
- ✅ 特征提取和标准化
|
|||
|
|
- ✅ 质量过滤,只返回合格特征
|
|||
|
|
- ✅ 支持单人和多人脸处理
|
|||
|
|
- ✅ 可配置的质量阈值
|
|||
|
|
|
|||
|
|
## 快速开始
|
|||
|
|
|
|||
|
|
### 安装依赖
|
|||
|
|
```bash
|
|||
|
|
pip install opencv-python numpy onnxruntime
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 基础使用
|
|||
|
|
```python
|
|||
|
|
import cv2
|
|||
|
|
from face_feature_extractor import extract_face_feature
|
|||
|
|
|
|||
|
|
# 读取图像
|
|||
|
|
image = cv2.imread("person.jpg")
|
|||
|
|
|
|||
|
|
# 提取特征(自动质量过滤)
|
|||
|
|
feature = extract_face_feature(image)
|
|||
|
|
|
|||
|
|
if feature is not None:
|
|||
|
|
print(f"特征维度: {feature.shape}")
|
|||
|
|
print(f"特征范数: {np.linalg.norm(feature):.6f}")
|
|||
|
|
else:
|
|||
|
|
print("特征提取失败(质量检查未通过或未检测到人脸)")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 核心 API
|
|||
|
|
|
|||
|
|
### FaceFeatureExtractor 类
|
|||
|
|
|
|||
|
|
#### 构造函数
|
|||
|
|
```python
|
|||
|
|
FaceFeatureExtractor(config: Optional[Dict] = None)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**参数:**
|
|||
|
|
- `config`: 可选配置字典,如果为None则使用默认配置
|
|||
|
|
|
|||
|
|
**示例:**
|
|||
|
|
```python
|
|||
|
|
# 使用默认配置
|
|||
|
|
extractor = FaceFeatureExtractor()
|
|||
|
|
|
|||
|
|
# 使用自定义配置
|
|||
|
|
config = {
|
|||
|
|
"detection": {"score_threshold": 0.5},
|
|||
|
|
"quality": {"strict_mode": False}
|
|||
|
|
}
|
|||
|
|
extractor = FaceFeatureExtractor(config)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 主要方法
|
|||
|
|
|
|||
|
|
##### 1. extract_single_feature()
|
|||
|
|
```python
|
|||
|
|
extract_single_feature(image: np.ndarray) -> Optional[np.ndarray]
|
|||
|
|
```
|
|||
|
|
提取单个人脸特征(质量过滤后)
|
|||
|
|
|
|||
|
|
**参数:**
|
|||
|
|
- `image`: 输入图像,BGR格式,numpy.ndarray
|
|||
|
|
|
|||
|
|
**返回:**
|
|||
|
|
- `np.ndarray`: 质量合格的特征向量
|
|||
|
|
- `None`: 未检测到人脸或质量不合格
|
|||
|
|
|
|||
|
|
**示例:**
|
|||
|
|
```python
|
|||
|
|
feature = extractor.extract_single_feature(image)
|
|||
|
|
if feature is not None:
|
|||
|
|
print(f"成功提取特征: {feature.shape}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 2. extract_multiple_features()
|
|||
|
|
```python
|
|||
|
|
extract_multiple_features(image: np.ndarray) -> List[np.ndarray]
|
|||
|
|
```
|
|||
|
|
提取多个人脸特征
|
|||
|
|
|
|||
|
|
**参数:**
|
|||
|
|
- `image`: 输入图像,BGR格式
|
|||
|
|
|
|||
|
|
**返回:**
|
|||
|
|
- `List[np.ndarray]`: 质量合格的特征向量列表
|
|||
|
|
|
|||
|
|
**示例:**
|
|||
|
|
```python
|
|||
|
|
features = extractor.extract_multiple_features(image)
|
|||
|
|
print(f"检测到 {len(features)} 个质量合格的人脸")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 3. extract_features()
|
|||
|
|
```python
|
|||
|
|
extract_features(image: np.ndarray,
|
|||
|
|
return_all_faces: bool = False,
|
|||
|
|
quality_filter: bool = True) -> FeatureExtractionResult
|
|||
|
|
```
|
|||
|
|
详细特征提取(包含所有信息)
|
|||
|
|
|
|||
|
|
**参数:**
|
|||
|
|
- `image`: 输入图像
|
|||
|
|
- `return_all_faces`: 是否返回所有人脸(包括质量不合格的)
|
|||
|
|
- `quality_filter`: 是否进行质量过滤
|
|||
|
|
|
|||
|
|
**返回:**
|
|||
|
|
- `FeatureExtractionResult`: 包含人脸信息、质量评分、处理时间等
|
|||
|
|
|
|||
|
|
**示例:**
|
|||
|
|
```python
|
|||
|
|
result = extractor.extract_features(image, return_all_faces=True, quality_filter=False)
|
|||
|
|
print(f"检测到 {len(result.faces)} 个人脸")
|
|||
|
|
for face in result.faces:
|
|||
|
|
print(f"置信度: {face.confidence:.3f}")
|
|||
|
|
print(f"质量合格: {face.quality_scores['overall']['passed']}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
##### 4. get_statistics()
|
|||
|
|
```python
|
|||
|
|
get_statistics() -> Dict[str, Any]
|
|||
|
|
```
|
|||
|
|
获取模块统计信息
|
|||
|
|
|
|||
|
|
**返回:**
|
|||
|
|
- `Dict`: 包含处理次数、成功率、平均处理时间等统计
|
|||
|
|
|
|||
|
|
## 便捷函数
|
|||
|
|
|
|||
|
|
### extract_face_feature()
|
|||
|
|
```python
|
|||
|
|
extract_face_feature(image: np.ndarray, config: Optional[Dict] = None) -> Optional[np.ndarray]
|
|||
|
|
```
|
|||
|
|
提取单个人脸特征的便捷函数
|
|||
|
|
|
|||
|
|
### extract_face_features()
|
|||
|
|
```python
|
|||
|
|
extract_face_features(image: np.ndarray, config: Optional[Dict] = None) -> List[np.ndarray]
|
|||
|
|
```
|
|||
|
|
提取多个人脸特征的便捷函数
|
|||
|
|
|
|||
|
|
## 配置选项
|
|||
|
|
|
|||
|
|
### 默认配置结构
|
|||
|
|
```python
|
|||
|
|
config = {
|
|||
|
|
"model_paths": {
|
|||
|
|
"detector": "./checkpoints/faceboxesv2-640x640.onnx",
|
|||
|
|
"landmk1": "./checkpoints/face_landmarker_pts5_net1.onnx",
|
|||
|
|
"landmk2": "./checkpoints/face_landmarker_pts5_net2.onnx",
|
|||
|
|
"recognizer": "./checkpoints/face_recognizer.onnx",
|
|||
|
|
"rotifier": "./checkpoints/model_gray_mobilenetv2_rotcls.onnx",
|
|||
|
|
"num_threads": 4
|
|||
|
|
},
|
|||
|
|
"detection": {
|
|||
|
|
"score_threshold": 0.35, # 检测置信度阈值
|
|||
|
|
"iou_threshold": 0.45, # NMS IoU阈值
|
|||
|
|
"max_faces": 1 # 最大处理人脸数
|
|||
|
|
},
|
|||
|
|
"quality": {
|
|||
|
|
"brightness": {
|
|||
|
|
"v0": 69.0, "v1": 70.0, "v2": 230.0, "v3": 231.0
|
|||
|
|
},
|
|||
|
|
"resolution": {
|
|||
|
|
"height": 112, "width": 112
|
|||
|
|
},
|
|||
|
|
"clarity": {
|
|||
|
|
"low_thrd": 0.10, "high_thrd": 0.20
|
|||
|
|
},
|
|||
|
|
"pose": {
|
|||
|
|
"yaw_thrd": 30.0, "pitch_thrd": 25.0,
|
|||
|
|
"var_onnx_path": "./checkpoints/fsanet-var.onnx",
|
|||
|
|
"conv_onnx_path": "./checkpoints/fsanet-conv.onnx"
|
|||
|
|
},
|
|||
|
|
"strict_mode": True # 严格模式,所有质量检查都通过
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 质量评估说明
|
|||
|
|
|
|||
|
|
模块会对每个人脸进行以下质量检查:
|
|||
|
|
|
|||
|
|
1. **亮度检查**: 确保人脸亮度在合理范围内
|
|||
|
|
2. **分辨率检查**: 确保人脸分辨率足够高
|
|||
|
|
3. **清晰度检查**: 确保图像清晰度良好
|
|||
|
|
4. **姿态检查**: 确保人脸姿态正对摄像头
|
|||
|
|
|
|||
|
|
在严格模式下,只有所有检查都通过才会返回特征。
|
|||
|
|
|
|||
|
|
## 数据结构
|
|||
|
|
|
|||
|
|
### FaceInfo
|
|||
|
|
```python
|
|||
|
|
@dataclass
|
|||
|
|
class FaceInfo:
|
|||
|
|
bbox: Tuple[float, float, float, float] # 人脸边界框
|
|||
|
|
landmarks: List[Tuple[float, float]] # 5个关键点
|
|||
|
|
confidence: float # 检测置信度
|
|||
|
|
quality_scores: Dict[str, Any] # 质量评分
|
|||
|
|
feature: Optional[np.ndarray] # 特征向量
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### FeatureExtractionResult
|
|||
|
|
```python
|
|||
|
|
@dataclass
|
|||
|
|
class FeatureExtractionResult:
|
|||
|
|
success: bool # 是否成功
|
|||
|
|
faces: List[FaceInfo] # 检测到的人脸列表
|
|||
|
|
processing_time: float # 处理时间
|
|||
|
|
error_message: Optional[str] # 错误信息
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 使用示例
|
|||
|
|
|
|||
|
|
### 示例1: 单人注册
|
|||
|
|
```python
|
|||
|
|
import cv2
|
|||
|
|
from face_feature_extractor import FaceFeatureExtractor
|
|||
|
|
|
|||
|
|
# 初始化
|
|||
|
|
extractor = FaceFeatureExtractor()
|
|||
|
|
|
|||
|
|
# 读取图像
|
|||
|
|
image = cv2.imread("user_photo.jpg")
|
|||
|
|
|
|||
|
|
# 提取特征
|
|||
|
|
feature = extractor.extract_single_feature(image)
|
|||
|
|
|
|||
|
|
if feature is not None:
|
|||
|
|
# 保存特征到数据库
|
|||
|
|
save_feature_to_database(user_id="user123", feature=feature)
|
|||
|
|
print("用户注册成功")
|
|||
|
|
else:
|
|||
|
|
print("注册失败,请使用质量更好的照片")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 示例2: 人脸识别
|
|||
|
|
```python
|
|||
|
|
import cv2
|
|||
|
|
import numpy as np
|
|||
|
|
from face_feature_extractor import FaceFeatureExtractor
|
|||
|
|
|
|||
|
|
def recognize_user(image):
|
|||
|
|
extractor = FaceFeatureExtractor()
|
|||
|
|
|
|||
|
|
# 提取待识别人脸特征
|
|||
|
|
unknown_feature = extractor.extract_single_feature(image)
|
|||
|
|
if unknown_feature is None:
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
# 从数据库加载已知特征
|
|||
|
|
known_features = load_features_from_database()
|
|||
|
|
|
|||
|
|
# 计算相似度
|
|||
|
|
best_match = None
|
|||
|
|
best_similarity = 0.0
|
|||
|
|
|
|||
|
|
for user_id, known_feature in known_features.items():
|
|||
|
|
similarity = np.dot(unknown_feature, known_feature)
|
|||
|
|
if similarity > best_similarity and similarity > 0.7:
|
|||
|
|
best_similarity = similarity
|
|||
|
|
best_match = user_id
|
|||
|
|
|
|||
|
|
return best_match, best_similarity
|
|||
|
|
|
|||
|
|
# 使用
|
|||
|
|
image = cv2.imread("test_photo.jpg")
|
|||
|
|
user_id, similarity = recognize_user(image)
|
|||
|
|
if user_id:
|
|||
|
|
print(f"识别成功: {user_id}, 相似度: {similarity:.6f}")
|
|||
|
|
else:
|
|||
|
|
print("识别失败")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 示例3: 批量处理
|
|||
|
|
```python
|
|||
|
|
import os
|
|||
|
|
import cv2
|
|||
|
|
from face_feature_extractor import FaceFeatureExtractor
|
|||
|
|
|
|||
|
|
def batch_process_images(image_dir):
|
|||
|
|
extractor = FaceFeatureExtractor()
|
|||
|
|
results = {}
|
|||
|
|
|
|||
|
|
for filename in os.listdir(image_dir):
|
|||
|
|
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
|
|||
|
|
image_path = os.path.join(image_dir, filename)
|
|||
|
|
image = cv2.imread(image_path)
|
|||
|
|
|
|||
|
|
if image is not None:
|
|||
|
|
feature = extractor.extract_single_feature(image)
|
|||
|
|
if feature is not None:
|
|||
|
|
results[filename] = feature
|
|||
|
|
print(f"✓ {filename}: 特征提取成功")
|
|||
|
|
else:
|
|||
|
|
print(f"✗ {filename}: 质量不合格")
|
|||
|
|
|
|||
|
|
return results
|
|||
|
|
|
|||
|
|
# 使用
|
|||
|
|
features = batch_process_images("./photos/")
|
|||
|
|
print(f"成功处理 {len(features)} 张图像")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 性能优化建议
|
|||
|
|
|
|||
|
|
1. **复用实例**: 对于批量处理,复用 `FaceFeatureExtractor` 实例
|
|||
|
|
2. **调整线程数**: 根据硬件调整 `num_threads` 参数
|
|||
|
|
3. **质量阈值**: 根据应用场景调整质量阈值
|
|||
|
|
4. **图像预处理**: 确保输入图像质量良好
|
|||
|
|
|
|||
|
|
## 错误处理
|
|||
|
|
|
|||
|
|
### 常见错误及解决方案
|
|||
|
|
|
|||
|
|
1. **未检测到人脸**
|
|||
|
|
- 确保图像中包含清晰的人脸
|
|||
|
|
- 调整检测阈值 `score_threshold`
|
|||
|
|
|
|||
|
|
2. **质量检查未通过**
|
|||
|
|
- 使用更好的光照条件
|
|||
|
|
- 确保人脸姿态正对摄像头
|
|||
|
|
- 调整质量阈值或关闭严格模式
|
|||
|
|
|
|||
|
|
3. **模型加载失败**
|
|||
|
|
- 检查模型文件路径是否正确
|
|||
|
|
- 确保模型文件完整且未损坏
|
|||
|
|
|
|||
|
|
4. **处理速度慢**
|
|||
|
|
- 减少 `num_threads` 参数
|
|||
|
|
- 降低输入图像分辨率
|
|||
|
|
- 使用 GPU 版本的 ONNX Runtime
|
|||
|
|
|
|||
|
|
## 更新日志
|
|||
|
|
|
|||
|
|
### v1.0.0
|
|||
|
|
- 初始版本发布
|
|||
|
|
- 支持基础特征提取功能
|
|||
|
|
- 集成质量评估系统
|
|||
|
|
- 提供完整的 API 接口
|
|||
|
|
|
|||
|
|
## 技术支持
|
|||
|
|
|
|||
|
|
如有问题或建议,请查看:
|
|||
|
|
- 测试代码: `test_feature_extractor.py`
|
|||
|
|
- 使用示例: `feature_extractor_examples.py`
|
|||
|
|
- 错误日志: 模块会输出详细的调试信息
|