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
Then we just need to activate it.
source env/bin/activate
This example requires only the opencv-python so we will define this in the "requirements.txt" file.
opencv-python
Save it and then install the requirements via:
pip install -r requirements.txt
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
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
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
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
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()
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
If all goes well the following should be displayed:
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.
Top comments (1)
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?