picpocket / test /howcuteami.py
chenchaoyun
fix
8a25edd
import cv2
import math
import argparse
import numpy as np
import os
# detect face
def highlightFace(net, frame, conf_threshold=0.95):
frameOpencvDnn = frame.copy()
frameHeight = frameOpencvDnn.shape[0]
frameWidth = frameOpencvDnn.shape[1]
blob = cv2.dnn.blobFromImage(
frameOpencvDnn, 1.0, (300, 300), [104, 117, 123], True, False
)
net.setInput(blob)
detections = net.forward()
faceBoxes = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > conf_threshold:
x1 = int(detections[0, 0, i, 3] * frameWidth)
y1 = int(detections[0, 0, i, 4] * frameHeight)
x2 = int(detections[0, 0, i, 5] * frameWidth)
y2 = int(detections[0, 0, i, 6] * frameHeight)
faceBoxes.append(scale([x1, y1, x2, y2]))
return faceBoxes
# scale current rectangle to box
def scale(box):
width = box[2] - box[0]
height = box[3] - box[1]
maximum = max(width, height)
dx = int((maximum - width) / 2)
dy = int((maximum - height) / 2)
bboxes = [box[0] - dx, box[1] - dy, box[2] + dx, box[3] + dy]
return bboxes
# crop image
def cropImage(image, box):
num = image[box[1] : box[3], box[0] : box[2]]
return num
# main
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--image", type=str, required=False, help="input image")
args = parser.parse_args()
# 创建输出目录
output_dir = "../output"
if not os.path.exists(output_dir):
os.makedirs(output_dir)
faceProto = "models/opencv_face_detector.pbtxt"
faceModel = "models/opencv_face_detector_uint8.pb"
ageProto = "models/age_googlenet.prototxt"
ageModel = "models/age_googlenet.caffemodel"
genderProto = "models/gender_googlenet.prototxt"
genderModel = "models/gender_googlenet.caffemodel"
beautyProto = "models/beauty_resnet.prototxt"
beautyModel = "models/beauty_resnet.caffemodel"
MODEL_MEAN_VALUES = (104, 117, 123)
ageList = [
"(0-2)",
"(4-6)",
"(8-12)",
"(15-20)",
"(25-32)",
"(38-43)",
"(48-53)",
"(60-100)",
]
genderList = ["Male", "Female"]
# 定义性别对应的颜色 (BGR格式)
gender_colors = {
"Male": (255, 165, 0), # 橙色 Orange
"Female": (255, 0, 255), # 洋红 Magenta / Fuchsia
}
faceNet = cv2.dnn.readNet(faceModel, faceProto)
ageNet = cv2.dnn.readNet(ageModel, ageProto)
genderNet = cv2.dnn.readNet(genderModel, genderProto)
beautyNet = cv2.dnn.readNet(beautyModel, beautyProto)
# 读取图片
image_path = args.image if args.image else "images/charlize.jpg"
frame = cv2.imread(image_path)
if frame is None:
print(f"无法读取图片: {image_path}")
exit()
faceBoxes = highlightFace(faceNet, frame)
if not faceBoxes:
print("No face detected")
exit()
print(f"检测到 {len(faceBoxes)} 张人脸")
for i, faceBox in enumerate(faceBoxes):
# 提取人脸区域
face = cropImage(frame, faceBox)
face_resized = cv2.resize(face, (224, 224))
# gender net
blob = cv2.dnn.blobFromImage(
face_resized, 1.0, (224, 224), MODEL_MEAN_VALUES, swapRB=False
)
genderNet.setInput(blob)
genderPreds = genderNet.forward()
gender = genderList[genderPreds[0].argmax()]
print(f"Gender: {gender}")
# age net
ageNet.setInput(blob)
agePreds = ageNet.forward()
age = ageList[agePreds[0].argmax()]
print(f"Age: {age[1:-1]} years")
# beauty net
blob = cv2.dnn.blobFromImage(
face_resized, 1.0 / 255, (224, 224), MODEL_MEAN_VALUES, swapRB=False
)
beautyNet.setInput(blob)
beautyPreds = beautyNet.forward()
beauty = round(2.0 * sum(beautyPreds[0]), 1)
print(f"Beauty: {beauty}/10.0")
# 根据性别选择颜色
color = gender_colors[gender]
# 保存人脸图片 - 使用cv2.imwrite
face_filename = f"{output_dir}/face_{i+1}.webp"
cv2.imwrite(face_filename, face, [cv2.IMWRITE_WEBP_QUALITY, 95])
print(f"人脸图片已保存: {face_filename}")
# 保存评分到图片上(可选)
face_with_text = face.copy()
cv2.putText(
face_with_text, f"{gender}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color, 2
)
cv2.putText(
face_with_text,
f"{age[1:-1]} years",
(10, 60),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
color,
2,
)
cv2.putText(
face_with_text,
f"{beauty}/10.0",
(10, 90),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
color,
2,
)
annotated_filename = f"{output_dir}/face_{i+1}_annotated.webp"
cv2.imwrite(annotated_filename, face_with_text, [cv2.IMWRITE_WEBP_QUALITY, 95])
print(f"标注人脸已保存: {annotated_filename}")
# 在原图上绘制人脸框和信息
cv2.rectangle(
frame,
(faceBox[0], faceBox[1]),
(faceBox[2], faceBox[3]),
color,
int(round(frame.shape[0] / 400)),
8,
)
cv2.putText(
frame,
f"{gender}, {age}, {beauty}",
(faceBox[0], faceBox[1] - 10),
cv2.FONT_HERSHEY_SIMPLEX,
1.25,
color,
2,
cv2.LINE_AA,
)
# 保存完整的标注图片
result_filename = f"{output_dir}/result_full.webp"
cv2.imwrite(result_filename, frame, [cv2.IMWRITE_WEBP_QUALITY, 95])
print(f"完整结果图片已保存: {result_filename}")
# 显示图片
cv2.imshow("howbeautifulami", frame)
cv2.waitKey(0)
cv2.destroyAllWindows()