DEV Community

Cover image for Simple Age and Gender detection using Python and OpenCV
Ethan
Ethan

Posted on

Simple Age and Gender detection using Python and OpenCV

Introduction

Hello! In this tutorial I will show how to create a simple age and gender detector using Python and OpenCV. 😃

Requirements

  • Python 3

Creating the python virtual environment

Creating a virtualenv using python 3 is very simple and you don't need to install any modules etc.

python3 -m venv env
Enter fullscreen mode Exit fullscreen mode

Then we just need to activate it.

source env/bin/activate
Enter fullscreen mode Exit fullscreen mode

This example requires only the opencv-python so we will define this in the "requirements.txt" file.

opencv-python
Enter fullscreen mode Exit fullscreen mode

Save it and then install the requirements via:

pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

This will install opencv-python into the virtual environment that was created.


Downloading the necessary models/weights

The models and weights needed for this can be found via:
https://github.com/ethand91/python-gender-age-detect/tree/master/weights

All you need to do is download them and put them into a directory called "weights".


Creating the Python file

Now we can finally get started writing Python, first we need to import the required modules.

1. Importing the modules

import cv2
import math
import sys
Enter fullscreen mode Exit fullscreen mode

2. Define the model/weight files

Next we need to define and load the models and weights etc.

# Defined the model files
FACE_PROTO = "weights/opencv_face_detector.pbtxt"
FACE_MODEL = "weights/opencv_face_detector_uint8.pb"

AGE_PROTO = "weights/age_deploy.prototxt"
AGE_MODEL = "weights/age_net.caffemodel"

GENDER_PROTO = "weights/gender_deploy.prototxt"
GENDER_MODEL = "weights/gender_net.caffemodel"

# Load network
FACE_NET = cv2.dnn.readNet(FACE_MODEL, FACE_PROTO)
AGE_NET = cv2.dnn.readNet(AGE_MODEL, AGE_PROTO)
GENDER_NET = cv2.dnn.readNet(GENDER_MODEL, GENDER_PROTO)

MODEL_MEAN_VALUES = (78.4263377603, 87.7689143744, 114.895847746)
AGE_LIST = ["(0-2)", "(4-6)", "(8-12)", "(15-20)", "(25-32)", "(38-43)", "(48-53)", "(60-100)"]
GENDER_LIST = ["Male", "Female"]

box_padding = 20
Enter fullscreen mode Exit fullscreen mode

3. Getting the bounding box coordinates

Next we need to get the face coordinates and we also draw a rectangle on the image via the following:

def get_face_box (net, frame, conf_threshold = 0.7):
  frame_copy = frame.copy()
  frame_height = frame_copy.shape[0]
  frame_width = frame_copy.shape[1]
  blob = cv2.dnn.blobFromImage(frame_copy, 1.0, (300, 300), [104, 117, 123], True, False)

  net.setInput(blob)
  detections = net.forward()
  boxes = []

  for i in range(detections.shape[2]):
    confidence = detections[0, 0, i, 2]

    if confidence > conf_threshold:
      x1 = int(detections[0, 0, i, 3] * frame_width)
      y1 = int(detections[0, 0, i, 4] * frame_height)
      x2 = int(detections[0, 0, i, 5] * frame_width)
      y2 = int(detections[0, 0, i, 6] * frame_height)
      boxes.append([x1, y1, x2, y2])
      cv2.rectangle(frame_copy, (x1, y1), (x2, y2), (0, 255, 0), int(round(frame_height / 150)), 8)

  return frame_copy, boxes
Enter fullscreen mode Exit fullscreen mode

4. Predicting age and gender

Next we use the following to predict the age and gender of the person, we also draw the age and gender on the image via:

def age_gender_detector (input_path):
  image = cv2.imread(input_path)
  resized_image = cv2.resize(image, (640, 480))

  frame = resized_image.copy()
  frame_face, boxes = get_face_box(FACE_NET, frame)

  for box in boxes:
    face = frame[max(0, box[1] - box_padding):min(box[3] + box_padding, frame.shape[0] - 1), \
      max(0, box[0] - box_padding):min(box[2] + box_padding, frame.shape[1] - 1)]

    blob = cv2.dnn.blobFromImage(face, 1.0, (227, 227), MODEL_MEAN_VALUES, swapRB = False)
    GENDER_NET.setInput(blob)
    gender_predictions = GENDER_NET.forward()
    gender = GENDER_LIST[gender_predictions[0].argmax()]
    print("Gender: {}, conf: {:.3f}".format(gender, gender_predictions[0].max()))

    AGE_NET.setInput(blob)
    age_predictions = AGE_NET.forward()
    age = AGE_LIST[age_predictions[0].argmax()]
    print("Age: {}, conf: {:.3f}".format(age, age_predictions[0].max()))

    label = "{},{}".format(gender, age)
    cv2.putText(frame_face, label, (box[0], box[1] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 255), 2, cv2.LINE_AA)

  return frame_face
Enter fullscreen mode Exit fullscreen mode

5. Writing main

Finally we write the starting point of the program:

if __name__ == "__main__":
  output = age_gender_detector(sys.argv[1])
  cv2.imwrite("output/output.jpg", output)
  cv2.imshow("Output", output)

  cv2.waitKey(0)
  cv2.destroyAllWindows()
Enter fullscreen mode Exit fullscreen mode

Here we take the file path as argv[1] and predict the age and gender of the people in the image.
The output is also written to the output directory (you may need to create this directory before running).

After this the output is shown to the user until the user presses any key.
Usage example:

python main.py lena.jpg
Enter fullscreen mode Exit fullscreen mode

If all goes well the following should be displayed:

Image

Feel free to try it with different images.

Github Repo:
https://github.com/ethand91/python-gender-age-detect


Like me work? I post about a variety of topics, if you would like to see more please like and follow me.
Also I love coffee.

“Buy Me A Coffee”

Latest comments (1)

Collapse
 
pritamsay profile image
pritamsay

Not getting the age and gender properly. Detecting Male as Female and vice-versa.

Should it need more training? Should I add more images to it?