【计算机视觉40例】案例40:识别性别与年龄

发布于:2023-01-20 ⋅ 阅读:(5) ⋅ 点赞:(0) ⋅ 评论:(0)

导读】本文是专栏《计算机视觉40例简介》的第40个案例《识别性别与年龄》。该专栏简要介绍李立宗主编《计算机视觉40例——从入门到深度学习(OpenCV-Python)》一书的40个案例。

目前,该书已经在电子工业出版社出版,大家可以在京东、淘宝、当当等平台购买。

大家可以在公众号“计算机视觉之光”回复关键字【案例40】获取本文案例的源代码及使用的测试图片等资料。

针对本书40个案例的每一个案例,分别录制了介绍视频。如果嫌看文字版麻烦,可以关注公众号“计算机视觉之光”直接观看视频介绍版。

本文简要介绍了本案例的一些基础知识,更详细的理论介绍、代码实现等内容请参考《计算机视觉40例简介》第28章《人脸识别应用案例》以获取更详细信息。

识别年龄和性别是一个有趣的应用,在很多场合我们都可以看到该应用。本文中,我们使用OpenCV自带的人脸检测器及Levi等人设计的卷积神经网络模型识别人脸对应的年龄和性别。

Levi等人在《Age and Gender Classification Using Convolutional Neural Networks》中提出了一种训练数据有限时也具有较好性能的卷积神经网络。其提出的网络模型如图1所示,它包含三个卷积层和两个全连接层。第一个卷积层包含 96 个7×7像素的卷积核,第二个卷积层包含 256 个 5×5 像素的卷积核,第三个卷积层包含 384 个3×3像素的卷积核。卷积层后面的两个全连接层,每个层包含 512 个神经元。最后的输出是每个分类所对应的标签。

 

1 网络结构

其具体结构如图2所示,在第一个卷积层和第二个卷积层的后面都有ReLU层、最大池化层、局部响应归一化层 (Local Response Normalization,LRN) 。在第三个卷积层的后面仅有ReLU层、最大池化层。全连接层都具有512个神经元,第一个全连接层接收第三个卷积层的输入,第二个全连接层接收第一个全连接层的512个输出作为输入,两个全连接层后面都伴有ReLU层、随机失活(dropout)层。最后的输出是所有年龄、性别所对应的分类标签。

 

图2 具体结构

Levi等针对该论文在github上提供了官方网页,可以下载相应的实现代码和训练好的模型,本节使用的模型即来源于其官方网页。

识别年龄和性别核心代码:

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

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)

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

    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

运行程序,程序运行结果如图3所示。

 

3  运算结果

在《计算机视觉40例——从入门到深度学习(OpenCV-Python)》第28章《人脸识别应用案例》中详细介绍了人脸表情识别、驾驶员疲劳监测、易容术、识别性别与年龄等案例。

《计算机视觉40例——从入门到深度学习(OpenCV-Python)》在介绍Python基础、OpenCV基础、计算机视觉理论基础、深度学习理论的基础上,介绍了计算机视觉领域内具有代表性的40个典型案例。这些案例中,既有传统的案例(数字识别、答题卡识别、物体计数、缺陷检测、手势识别、隐身术、以图搜图、车牌识别、图像加密、指纹识别等),也有深度学习案例(图像分类、风格迁移、姿势识别、实例分割等),还有人脸识别方面的案例(表情识别、驾驶员疲劳监测、识别性别与年龄等)。

 


网站公告

欢迎关注微信公众号

今日签到

点亮在社区的每一天
签到