Gender and Age Detection with OpenCV
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 :
import cv2
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) net.setInput(blob) 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.
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.
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.
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
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) genderNet.setInput(blob) genderPreds = genderNet.forward() gender = genderList[genderPreds[0].argmax()] print(f'Gender: {gender}') ageNet.setInput(blob) 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) cv2.waitKey(0)