python+opencv实现人脸、年龄、性别识别

365 阅读2分钟

import cv2

# 模型(网络模型/预训练模型):face/age/gender(人脸、年龄、性别)

faceProto = "model/opencv_face_detector.pbtxt"
faceModel = "model/opencv_face_detector_uint8.pb"
ageProto = "model/deploy_age.prototxt"
ageModel = "model/age_net.caffemodel"
genderProto = "model/deploy_gender.prototxt"
genderModel = "model/gender_net.caffemodel"

# 加载网络

ageNet = cv2.dnn.readNet(ageModel, ageProto) # 年龄
genderNet = cv2.dnn.readNet(genderModel, genderProto) # 性别
faceNet = cv2.dnn.readNet(faceModel, faceProto) # 人脸

# ============变量初始化============

# 年龄段和性别

ageList = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(25-32)', '(38-43)', '(48-53)', '(60-100)']
genderList = ['Male', 'Female']
mean = (78.4263377603, 87.7689143744, 114.895847746) # 模型均值

# ========自定义函数,获取人脸包围框========

def getBoxes(net, frame):
frameHeight, frameWidth = frame.shape[:2] # 获取高度、宽度

# 将图像(帧)处理为DNN可以接收的格式

blob = cv2.dnn.blobFromImage(frame, 1.0, (300, 300),
[104, 117, 123], True, False)

# 调用网络模型,检测人脸

net.setInput(blob)
detections = net.forward()

# faceBoxes存储检测到的人脸

faceBoxes = []
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.7: # 筛选,将置信度大于0.7的保留
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([x1, y1, x2, y2]) # 人脸框的坐标

# 绘制人脸框

cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), int(round(frameHeight / 150)), 6)

# 返回绘制了人脸框的帧frame、人脸包围框faceBoxes

return frame, faceBoxes

# ==========循环读取每一帧,并处理==========

cap = cv2.VideoCapture(0, cv2.CAP_DSHOW) # 装载摄像头
while True:

# 读一帧

_, frame = cap.read()

# 进行镜像处理,左右互换

frame = cv2.flip(frame, 1)

# 调用函数getBoxes,获取人脸包围框,绘制人脸包围框(可能有多个)

frame, faceBoxes = getBoxes(faceNet, frame)
if not faceBoxes: # 没有人脸时,检测下一帧,后续循环操作不再执行
print("当前帧内不存在人脸")
continue

# 遍历每一个人脸包围框

for faceBox in faceBoxes:

# 处理frame,将其处理为符合DNN输入要求的格式

blob = cv2.dnn.blobFromImage(frame, 1.0, (227, 227), mean)

# 调用模型,预测性别

genderNet.setInput(blob)
genderOuts = genderNet.forward()
gender = genderList[genderOuts[0].argmax()]

# 调用模型,预测年龄

ageNet.setInput(blob)
ageOuts = ageNet.forward()
age = ageList[ageOuts[0].argmax()]

# 格式化文本(年龄,性别)

result = "{},{}".format(gender, age)

# 输出性别和年龄

cv2.putText(frame, result, (faceBox[0], faceBox[1] - 10),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2,
cv2.LINE_AA)

# 显示性别、年龄

cv2.imshow("result", frame)

# 按下“Esc”键,退出程序

if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
cap.release()

模型链接:pan.baidu.com/s/17n-5ilS1…

提取码:zr51