• For any query, contact us at
  • +91-9872993883
  • +91-8283824812
  • info@ris-ai.com

Gender and Age detection for images with opencv Python

In this Python Project, we will use Deep Learning to accurately identify the gender and predict the age of a person from a single image of a face.

First we import the opencv-python :

In [1]:
import cv2

Now, we create a function for any face detector capable of producing bounding boxes for faces in an image.

In [2]:
def highlightFace(net, frame, conf_threshold=0.7):
    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)

    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([x1, y1, x2, y2])
            cv2.rectangle(frameOpencvDnn, (x1, y1), (x2, y2), (0, 255, 0), int(round(frameHeight/150)), 8)
    return frameOpencvDnn, faceBoxes

For face detection, we have a .pb file- this is a protobuf file (protocol buffer); it holds the graph definition and the trained weights of the model. We can use this to run the trained model. And while a .pb file holds the protobuf in binary format, one with the .pbtxt extension holds it in text format. These are TensorFlow files. For age and gender, the .prototxt files describe the network configuration and the .caffemodel file defines the internal states of the parameters of the layers.

For face, age, and gender, initialize protocol buffer and model.

In [3]:
faceProto = "opencv_face_detector.pbtxt"
faceModel = "opencv_face_detector_uint8.pb"
ageProto = "age_deploy.prototxt"
ageModel = "age_net.caffemodel"
genderProto = "gender_deploy.prototxt"
genderModel = "gender_net.caffemodel"

Initialize the mean values for the model and the lists of age ranges and genders to classify from.

In [4]:
MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
ageList = ['(0-2)', '(4-6)', '(8-12)', '(15-20)', '(22-25)', '(26-32)', '(38-43)', '(48-53)', '(60-100)']
genderList = ['Male', 'Female']

Now, use the readNet() method to load the networks. The first parameter holds trained weights and the second carries network configuration.

In [ ]:
faceNet = cv2.dnn.readNet(faceModel, faceProto)
ageNet = cv2.dnn.readNet(ageModel, ageProto)
genderNet = cv2.dnn.readNet(genderModel, genderProto)

Let's read the image names as frame.

And make a call to the highlightFace() function with the faceNet and frame parameters, and what this returns, we will store in the names resultImg and faceBoxes. And if we got 0 faceBoxes, it means there was no face to detect.

Here, net is faceNet- this model is the DNN Face Detector

In [ ]:
frame = cv2.imread("kid2.jpg")

padding = 20
resultImg, faceBoxes = highlightFace(faceNet, frame)
if not faceBoxes:
    print("No face detected")
for faceBox in faceBoxes:
    face = frame[max(0, faceBox[1]-padding): min(faceBox[3]+padding, frame.shape[0]-1), max(0, faceBox[0]-padding): min(faceBox[2]+padding, frame.shape[1]-1)]

    blob = cv2.dnn.blobFromImage(face, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB=False)
    genderPreds = genderNet.forward()
    gender = genderList[genderPreds[0].argmax()]
    print(f'Gender: {gender}')

    agePreds = ageNet.forward()
    age = ageList[agePreds[0].argmax()]
    print(f'Age: {age[1:-1]} years')
    cv2.putText(resultImg, f'{gender}, {age}', (faceBox[0], faceBox[1]-10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0,255,255), 2, cv2.LINE_AA)
    cv2.imshow("Detecting age and gender", resultImg)
Gender: Female
Age: 4-6 years
Gender and Age detection for images with opencv Python