多年龄段人脸数据集构建与标注
在跨年龄人脸识别领域,构建和标注高质量的多年龄段人脸数据集是至关重要的一步。数据集的质量直接影响到模型的训练效果和最终的识别准确率。本节将详细介绍如何构建和标注多年龄段人脸数据集,包括数据收集、预处理、标注方法和数据集的验证与测试。
数据收集
1. 数据源选择
构建多年龄段人脸数据集的第一步是选择合适的数据源。数据源可以是公开的数据库,也可以是自采的数据。公开数据集如LFW、MegaFace、AgeDB等,这些数据集包含了大量的不同年龄的人脸图像。自采数据则需要考虑数据的多样性和质量,可以通过网络爬虫、社交媒体、公共摄像头等途径获取。
公开数据集
-
LFW (Labeled Faces in the Wild): 包含5749个不同的人物,总共13233张图像。虽然没有专门针对年龄,但可以从中筛选出不同年龄的人脸图像。
-
MegaFace: 包含100万张图像,涵盖了不同年龄、种族和环境的人脸数据。
-
AgeDB: 专门用于跨年龄人脸识别的数据集,包含16488张图像,涵盖0-100岁的人脸数据。
自采数据
自采数据时需要确保数据的多样性和质量。可以通过以下途径收集数据:
-
网络爬虫: 使用Python的爬虫库(如
requests
和BeautifulSoup
)从互联网上抓取人脸图像。 -
社交媒体: 从Facebook、Instagram等社交平台获取公开的人脸图像。
-
公共摄像头: 从公共摄像头拍摄的人脸图像中提取数据。
2. 数据收集方法
网络爬虫
使用网络爬虫可以从互联网上收集大量的人脸图像。以下是一个简单的Python爬虫示例,从一个公开的人脸图像网站抓取图像:
import requests
from bs4 import BeautifulSoup
import os
def download_images(url, save_dir):
"""
从指定URL下载人脸图像并保存到指定目录
:param url: 网站URL
:param save_dir: 保存目录
"""
if not os.path.exists(save_dir):
os.makedirs(save_dir)
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有图像标签
img_tags = soup.find_all('img')
for img in img_tags:
img_url = img.get('src')
if img_url and 'face' in img_url: # 筛选包含人脸的图像
img_data = requests.get(img_url).content
img_name = os.path.basename(img_url)
with open(os.path.join(save_dir, img_name), 'wb') as f:
f.write(img_data)
# 示例:从一个公开的人脸图像网站抓取图像
url = 'https://example.com/faces'
save_dir = 'data/raw_faces'
download_images(url, save_dir)
社交媒体
从社交媒体获取人脸图像时,需要遵守平台的API限制和用户隐私政策。以下是一个使用Facebook Graph API获取公开用户人脸图像的示例:
import facebook
import requests
import os
def download_facebook_faces(access_token, save_dir):
"""
从Facebook获取公开用户的人脸图像
:param access_token: Facebook访问令牌
:param save_dir: 保存目录
"""
if not os.path.exists(save_dir):
os.makedirs(save_dir)
graph = facebook.GraphAPI(access_token)
# 获取用户的基本信息
user = graph.get_object('me', fields='id,name,picture')
img_url = user['picture']['data']['url']
img_data = requests.get(img_url).content
img_name = f"{user['id']}.jpg"
with open(os.path.join(save_dir, img_name), 'wb') as f:
f.write(img_data)
# 示例:从Facebook获取人脸图像
access_token = 'YOUR_ACCESS_TOKEN'
save_dir = 'data/facebook_faces'
download_facebook_faces(access_token, save_dir)
3. 数据预处理
数据预处理是数据集构建的重要步骤,包括图像的清洗、对齐和标准化。预处理的目的是确保数据集的质量,提高模型的训练效果。
图像清洗
图像清洗包括去除模糊、噪声和不完整的人脸图像。可以使用OpenCV等图像处理库进行图像清洗。
import cv2
import os
def clean_images(image_dir, output_dir):
"""
清洗图像,去除模糊和噪声图像
:param image_dir: 原始图像目录
:param output_dir: 清洗后的图像目录
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for filename in os.listdir(image_dir):
img_path = os.path.join(image_dir, filename)
img = cv2.imread(img_path)
if img is None:
continue
# 检测图像是否模糊
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
if laplacian_var > 50: # 阈值可以根据实际情况调整
cv2.imwrite(os.path.join(output_dir, filename), img)
# 示例:清洗图像
image_dir = 'data/raw_faces'
output_dir = 'data/clean_faces'
clean_images(image_dir, output_dir)
图像对齐
图像对齐是将人脸图像对齐到一个统一的标准,通常使用面部关键点检测(如Dlib库)进行对齐。
import dlib
import cv2
import os
import numpy as np
def align_face(image_path, predictor_path, output_path):
"""
对齐人脸图像
:param image_path: 原始图像路径
:param predictor_path: Dlib面部关键点检测模型路径
:param output_path: 对齐后的图像路径
"""
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
img = cv2.imread(image_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector(gray)
if len(faces) == 0:
return
for face in faces:
shape = predictor(gray, face)
shape_np = np.array([[shape.part(i).x, shape.part(i).y] for i in range(68)])
# 计算眼睛的中心点
left_eye_center = np.mean(shape_np[36:42], axis=0)
right_eye_center = np.mean(shape_np[42:48], axis=0)
# 计算旋转角度
dY = right_eye_center[1] - left_eye_center[1]
dX = right_eye_center[0] - left_eye_center[0]
angle = np.degrees(np.arctan2(dY, dX))
# 计算眼睛的中心
eyes_center = ((left_eye_center[0] + right_eye_center[0]) // 2,
(left_eye_center[1] + right_eye_center[1]) // 2)
# 计算旋转矩阵
M = cv2.getRotationMatrix2D(eyes_center, angle, 1.0)
# 进行旋转
(w, h) = img.shape[:2]
img_rotated = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_CUBIC)
# 裁剪对齐后的人脸
face_aligned = dlib.get_face_chips(img_rotated, [shape], size=256)[0]
# 保存对齐后的图像
cv2.imwrite(output_path, face_aligned)
# 示例:对齐人脸图像
image_path = 'data/clean_faces/face1.jpg'
predictor_path = 'models/shape_predictor_68_face_landmarks.dat'
output_path = 'data/aligned_faces/face1_aligned.jpg'
align_face(image_path, predictor_path, output_path)
图像标准化
图像标准化包括调整图像的尺寸、亮度、对比度等,确保图像的一致性。
import cv2
import os
def standardize_image(image_path, output_path, target_size=(112, 112)):
"""
标准化图像,调整尺寸和亮度
:param image_path: 原始图像路径
:param output_path: 标准化后的图像路径
:param target_size: 目标图像尺寸
"""
img = cv2.imread(image_path)
if img is None:
return
# 调整图像尺寸
img_resized = cv2.resize(img, target_size, interpolation=cv2.INTER_LINEAR)
# 调整图像亮度和对比度
img_normalized = cv2.normalize(img_resized, None, alpha=0, beta=255, norm_type=cv2.NORM_MINMAX)
# 保存标准化后的图像
cv2.imwrite(output_path, img_normalized)
# 示例:标准化图像
image_path = 'data/aligned_faces/face1_aligned.jpg'
output_path = 'data/standardized_faces/face1_standardized.jpg'
standardize_image(image_path, output_path)
数据标注
数据标注是为图像添加标签的过程,对于跨年龄人脸识别,标签通常包括年龄和身份信息。
1. 年龄标注
年龄标注可以通过人工标注或使用预训练的年龄估计模型进行。人工标注需要大量的人力,而预训练模型可以提高标注效率。
人工标注
人工标注可以通过标注工具(如LabelMe、Labelbox等)进行。以下是一个简单的LabelMe标注示例:
-
安装LabelMe:
pip install labelme
-
启动LabelMe:
labelme
-
标注年龄:
-
打开图像并标注年龄信息。
-
保存标注结果为JSON文件。
-
使用预训练模型标注
可以使用预训练的年龄估计模型(如Dex等)进行自动标注。以下是一个使用Dex模型进行年龄标注的示例:
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from PIL import Image
import os
import json
class AgeEstimator(nn.Module):
def __init__(self, model_path):
super(AgeEstimator, self).__init__()
self.model = torch.load(model_path)
self.transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
def forward(self, image):
image = self.transform(image)
image = image.unsqueeze(0)
output = self.model(image)
age = output.item()
return age
def annotate_age(image_dir, output_dir, model_path):
"""
使用预训练模型进行年龄标注
:param image_dir: 原始图像目录
:param output_dir: 标注结果目录
:param model_path: 预训练模型路径
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
age_estimator = AgeEstimator(model_path)
for filename in os.listdir(image_dir):
img_path = os.path.join(image_dir, filename)
image = Image.open(img_path)
age = age_estimator(image)
# 保存标注结果
result = {
'image': filename,
'age': age
}
output_path = os.path.join(output_dir, f"{os.path.splitext(filename)[0]}.json")
with open(output_path, 'w') as f:
json.dump(result, f)
# 示例:使用预训练模型进行年龄标注
image_dir = 'data/standardized_faces'
output_dir = 'data/age_annotations'
model_path = 'models/dex_age_estimation.pth'
annotate_age(image_dir, output_dir, model_path)
2. 身份标注
身份标注是指为图像添加身份信息,通常是通过人工标注或使用身份识别模型进行。人工标注需要大量的人力,而身份识别模型可以提高标注效率。
人工标注
人工标注可以通过标注工具(如LabelMe、Labelbox等)进行。以下是一个简单的LabelMe标注示例:
-
安装LabelMe:
pip install labelme
-
启动LabelMe:
labelme
-
标注身份:
-
打开图像并标注身份信息。
-
保存标注结果为JSON文件。
-
使用预训练模型标注
可以使用预训练的身份识别模型(如FaceNet等)进行自动标注。以下是一个使用FaceNet模型进行身份标注的示例:
import torch
import torchvision.transforms as transforms
from PIL import Image
import os
import json
import numpy as np
class IdentityRecognizer(nn.Module):
def __init__(self, model_path, embedding_path):
super(IdentityRecognizer, self).__init__()
self.model = torch.load(model_path)
self.transform = transforms.Compose([
transforms.Resize((160, 160)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
self.embeddings = np.load(embedding_path)
self.labels = ['Alice', 'Bob', 'Charlie', 'David', 'Eve'] # 假设身份标签
def forward(self, image):
image = self.transform(image)
image = image.unsqueeze(0)
embedding = self.model(image)
embedding = embedding.detach().numpy()
# 计算与已知身份的相似度
similarities = np.linalg.norm(self.embeddings - embedding, axis=1)
best_match_index = np.argmin(similarities)
identity = self.labels[best_match_index]
return identity
def annotate_identity(image_dir, output_dir, model_path, embedding_path):
"""
使用预训练模型进行身份标注
:param image_dir: 原始图像目录
:param output_dir: 标注结果目录
:param model_path: 预训练模型路径
:param embedding_path: 已知身份的嵌入向量路径
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
identity_recognizer = IdentityRecognizer(model_path, embedding_path)
for filename in os.listdir(image_dir):
img_path = os.path.join(image_dir, filename)
image = Image.open(img_path)
identity = identity_recognizer(image)
# 保存标注结果
result = {
'image': filename,
'identity': identity
}
output_path = os.path.join(output_dir, f"{os.path.splitext(filename)[0]}.json")
with open(output_path, 'w') as f:
json.dump(result, f)
# 示例:使用预训练模型进行身份标注
image_dir = 'data/standardized_faces'
output_dir = 'data/identity_annotations'
model_path = 'models/facenet.pth'
embedding_path = 'data/known_embeddings.npy'
annotate_identity(image_dir, output_dir, model_path, embedding_path)
数据集验证与测试
构建数据集后,需要进行验证和测试,确保数据集的质量和一致性。验证和测试包括数据集的分布分析、标注准确性验证等。
1. 数据集分布分析
数据集分布分析是指检查数据集中图像的年龄和身份分布,确保数据集的多样性和平衡性。
import os
import json
import matplotlib.pyplot as plt
def analyze_age_distribution(age_dir):
"""
分析年龄分布
:param age_dir: 年龄标注结果目录
"""
age_counts = {}
for filename in os.listdir(age_dir):
if filename.endswith('.json'):
with open(os.path.join(age_dir, filename), 'r') as f:
data = json.load(f)
age = data['age']
if age in age_counts:
age_counts[age] += 1
else:
age_counts[age] = 1
# 绘制年龄分布图
ages = list(age_counts.keys())
counts = list(age_counts.values())
plt.bar(ages, counts)
plt.xlabel('Age')
plt.ylabel('Count')
plt.title('Age Distribution')
plt.show()
# 示例:分析年龄分布
age_dir = 'data/age_annotations'
analyze_age_distribution(age_dir)
def analyze_identity_distribution(identity_dir):
"""
分析身份分布
:param identity_dir: 身份标注结果目录
"""
identity_counts = {}
for filename in os.listdir(identity_dir):
if filename.endswith('.json'):
with open(os.path.join(identity_dir, filename), 'r') as f:
data = json.load(f)
identity = data['identity']
if identity in identity_counts:
identity_counts[identity] += 1
else:
identity_counts[identity] = 1
# 绘制身份分布图
identities = list(identity_counts.keys())
counts = list(identity_counts.values())
plt.bar(identities, counts)
plt.xlabel('Identity')
plt.ylabel('Count')
plt.title('Identity Distribution')
plt.xticks(rotation=45)
plt.show()
# 示例:分析身份分布
identity_dir = 'data/identity_annotations'
analyze_identity_distribution(identity_dir)
2. 标注准确性验证
标注准确性验证是指检查标注的年龄和身份信息是否正确。可以通过人工抽查或使用模型进行验证。
人工抽查
人工抽查是指随机选取一部分图像进行人工检查,确保标注的准确性。以下是一个简单的Python代码示例,用于随机抽查并显示图像及其标注信息:
import os
import json
import cv2
import numpy as np
def check_annotations(image_dir, age_dir, identity_dir, num_samples=10):
"""
人工抽查标注的准确性
:param image_dir: 原始图像目录
:param age_dir: 年龄标注结果目录
:param identity_dir: 身份标注结果目录
:param num_samples: 抽查样本数量
"""
image_files = os.listdir(image_dir)
sample_indices = np.random.choice(len(image_files), num_samples, replace=False)
for idx in sample_indices:
filename = image_files[idx]
img_path = os.path.join(image_dir, filename)
age_path = os.path.join(age_dir, f"{os.path.splitext(filename)[0]}.json")
identity_path = os.path.join(identity_dir, f"{os.path.splitext(filename)[0]}.json")
# 读取图像
img = cv2.imread(img_path)
# 读取年龄标注
with open(age_path, 'r') as f:
age_data = json.load(f)
age = age_data['age']
# 读取身份标注
with open(identity_path, 'r') as f:
identity_data = json.load(f)
identity = identity_data['identity']
# 显示图像及其标注信息
cv2.imshow(f"Image: {filename}, Age: {age}, Identity: {identity}", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 示例:人工抽查标注的准确性
image_dir = 'data/standardized_faces'
age_dir = 'data/age_annotations'
identity_dir = 'data/identity_annotations'
check_annotations(image_dir, age_dir, identity_dir)
使用模型验证
使用模型验证是指通过训练一个简单的模型来检查标注的准确性。可以使用年龄估计模型和身份识别模型进行验证。
import torch
import torchvision.transforms as transforms
from PIL import Image
import os
import json
import numpy as np
class AgeEstimator(nn.Module):
def __init__(self, model_path):
super(AgeEstimator, self).__init__()
self.model = torch.load(model_path)
self.transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
def forward(self, image):
image = self.transform(image)
image = image.unsqueeze(0)
output = self.model(image)
age = output.item()
return age
class IdentityRecognizer(nn.Module):
def __init__(self, model_path, embedding_path):
super(IdentityRecognizer, self).__init__()
self.model = torch.load(model_path)
self.transform = transforms.Compose([
transforms.Resize((160, 160)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])
self.embeddings = np.load(embedding_path)
self.labels = ['Alice', 'Bob', 'Charlie', 'David', 'Eve'] # 假设身份标签
def forward(self, image):
image = self.transform(image)
image = image.unsqueeze(0)
embedding = self.model(image)
embedding = embedding.detach().numpy()
# 计算与已知身份的相似度
similarities = np.linalg.norm(self.embeddings - embedding, axis=1)
best_match_index = np.argmin(similarities)
identity = self.labels[best_match_index]
return identity
def validate_annotations(image_dir, age_dir, identity_dir, age_model_path, identity_model_path, embedding_path, num_samples=100):
"""
使用模型验证标注的准确性
:param image_dir: 原始图像目录
:param age_dir: 年龄标注结果目录
:param identity_dir: 身份标注结果目录
:param age_model_path: 年龄估计模型路径
:param identity_model_path: 身份识别模型路径
:param embedding_path: 已知身份的嵌入向量路径
:param num_samples: 验证样本数量
"""
image_files = os.listdir(image_dir)
sample_indices = np.random.choice(len(image_files), num_samples, replace=False)
age_estimator = AgeEstimator(age_model_path)
identity_recognizer = IdentityRecognizer(identity_model_path, embedding_path)
correct_age = 0
correct_identity = 0
for idx in sample_indices:
filename = image_files[idx]
img_path = os.path.join(image_dir, filename)
age_path = os.path.join(age_dir, f"{os.path.splitext(filename)[0]}.json")
identity_path = os.path.join(identity_dir, f"{os.path.splitext(filename)[0]}.json")
# 读取图像
image = Image.open(img_path)
# 读取年龄标注
with open(age_path, 'r') as f:
age_data = json.load(f)
true_age = age_data['age']
# 读取身份标注
with open(identity_path, 'r') as f:
identity_data = json.load(f)
true_identity = identity_data['identity']
# 使用模型估计年龄
estimated_age = age_estimator(image)
# 使用模型识别身份
estimated_identity = identity_recognizer(image)
# 检查估计年龄是否在标注年龄的合理范围内
if abs(estimated_age - true_age) <= 5: # 可以根据实际情况调整容忍范围
correct_age += 1
# 检查识别的身份是否正确
if estimated_identity == true_identity:
correct_identity += 1
# 计算准确率
age_accuracy = correct_age / num_samples
identity_accuracy = correct_identity / num_samples
print(f"Age Annotation Accuracy: {age_accuracy:.2f}")
print(f"Identity Annotation Accuracy: {identity_accuracy:.2f}")
# 示例:使用模型验证标注的准确性
image_dir = 'data/standardized_faces'
age_dir = 'data/age_annotations'
identity_dir = 'data/identity_annotations'
age_model_path = 'models/dex_age_estimation.pth'
identity_model_path = 'models/facenet.pth'
embedding_path = 'data/known_embeddings.npy'
validate_annotations(image_dir, age_dir, identity_dir, age_model_path, identity_model_path, embedding_path)
3. 数据集的最终整理
在完成数据收集、预处理和标注后,需要对数据集进行最终整理,确保其结构清晰、易于使用。以下是一个简单的Python代码示例,用于将标注结果和图像整理到一个结构化的数据集中:
import os
import json
import shutil
def organize_dataset(image_dir, age_dir, identity_dir, output_dir):
"""
整理数据集,将图像和标注结果保存到结构化的目录中
:param image_dir: 原始图像目录
:param age_dir: 年龄标注结果目录
:param identity_dir: 身份标注结果目录
:param output_dir: 输出目录
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for filename in os.listdir(image_dir):
img_path = os.path.join(image_dir, filename)
age_path = os.path.join(age_dir, f"{os.path.splitext(filename)[0]}.json")
identity_path = os.path.join(identity_dir, f"{os.path.splitext(filename)[0]}.json")
# 读取年龄标注
with open(age_path, 'r') as f:
age_data = json.load(f)
age = age_data['age']
# 读取身份标注
with open(identity_path, 'r') as f:
identity_data = json.load(f)
identity = identity_data['identity']
# 创建身份目录
identity_dir = os.path.join(output_dir, identity)
if not os.path.exists(identity_dir):
os.makedirs(identity_dir)
# 创建年龄子目录
age_dir = os.path.join(identity_dir, str(int(age)))
if not os.path.exists(age_dir):
os.makedirs(age_dir)
# 将图像移动到对应的年龄子目录
shutil.move(img_path, os.path.join(age_dir, filename))
# 清理原始目录
shutil.rmtree(image_dir)
shutil.rmtree(age_dir)
shutil.rmtree(identity_dir)
# 示例:整理数据集
image_dir = 'data/standardized_faces'
age_dir = 'data/age_annotations'
identity_dir = 'data/identity_annotations'
output_dir = 'data/organized_faces'
organize_dataset(image_dir, age_dir, identity_dir, output_dir)
4. 数据集的使用
最终整理好的数据集可以用于训练和测试跨年龄人脸识别模型。数据集的结构如下:
data/organized_faces/
├── Alice/
│ ├── 20/
│ │ ├── face1.jpg
│ │ ├── face2.jpg
│ │ └── ...
│ ├── 30/
│ │ ├── face1.jpg
│ │ ├── face2.jpg
│ │ └── ...
│ └── ...
├── Bob/
│ ├── 25/
│ │ ├── face1.jpg
│ │ ├── face2.jpg
│ │ └── ...
│ ├── 35/
│ │ ├── face1.jpg
│ │ ├── face2.jpg
│ │ └── ...
│ └── ...
└── ...
每个身份目录下包含多个年龄子目录,每个年龄子目录中包含对应年龄的人脸图像。这种结构有助于模型在训练过程中更好地学习不同年龄的人脸特征。
5. 数据集的扩展
为了进一步提高模型的泛化能力,可以考虑扩展数据集。扩展方法包括增加更多的数据源、使用数据增强技术等。
增加更多的数据源
可以继续从其他公开数据库和自采数据源收集人脸图像,增加数据集的多样性和数量。
数据增强
数据增强技术可以生成更多的训练样本,提高模型的鲁棒性。常见的数据增强方法包括旋转、缩放、裁剪、翻转等。
import cv2
import os
import numpy as np
def augment_images(image_dir, output_dir, num_augments=5):
"""
对图像进行数据增强
:param image_dir: 原始图像目录
:param output_dir: 增强后的图像目录
:param num_augments: 每张图像生成的增强数量
"""
if not os.path.exists(output_dir):
os.makedirs(output_dir)
for filename in os.listdir(image_dir):
img_path = os.path.join(image_dir, filename)
img = cv2.imread(img_path)
for i in range(num_augments):
# 随机旋转
angle = np.random.randint(-20, 20)
(h, w) = img.shape[:2]
center = (w // 2, h // 2)
M = cv2.getRotationMatrix2D(center, angle, 1.0)
rotated = cv2.warpAffine(img, M, (w, h))
# 随机缩放
scale = np.random.uniform(0.8, 1.2)
resized = cv2.resize(rotated, (0, 0), fx=scale, fy=scale)
# 随机裁剪
(h, w) = resized.shape[:2]
crop_size = (h // 2, w // 2)
x = np.random.randint(0, w - crop_size[1])
y = np.random.randint(0, h - crop_size[0])
cropped = resized[y:y+crop_size[0], x:x+crop_size[1]]
# 随机翻转
flip = np.random.choice([0, 1, -1])
if flip != 0:
flipped = cv2.flip(cropped, flip)
else:
flipped = cropped
# 保存增强后的图像
output_path = os.path.join(output_dir, f"{os.path.splitext(filename)[0]}_aug_{i}.jpg")
cv2.imwrite(output_path, flipped)
# 示例:对图像进行数据增强
image_dir = 'data/organized_faces/Alice/20'
output_dir = 'data/augmented_faces/Alice/20'
augment_images(image_dir, output_dir)
通过上述步骤,可以构建和标注一个高质量的多年龄段人脸数据集,为跨年龄人脸识别模型的训练和测试提供可靠的数据支持。