Opencv dnn实现人类性别检测和年龄预测
概述
?
前面我寫了很多篇關于OpenCV DNN應用相關的文章,這里再來一篇文章,用OpenCV DNN實現一個很有趣好玩的例子,基于Caffe的預訓練模型實現年齡與性別預測,這個在很多展會上都有展示,OpenCV DNN實現這里非常簡潔明了,總共不到100行的代碼。下面就來說一下怎么實現的,首先下載兩個Caffe的預訓練模型:
?
Gender Net and Age Net
https://www.dropbox.com/s/iyv483wz7ztr9gh/gender_net.caffemodel?dl=0"
https://www.dropbox.com/s/xfb20y596869vbb/age_net.caffemodel?dl=0"
上述兩個模型一個是預測性別的,一個是預測年齡的,性別預測返回的是一個二分類結果
Male Female年齡預測返回的是8個年齡的階段!
'(0-2)',? '(4-6)',? '(8-12)',? '(15-20)',? '(25-32)',? '(38-43)',? '(48-53)',? '(60-100)'人臉檢測是基于OPenCV DNN模塊自帶的殘差網絡的人臉檢測算法模型!非常的強大與好用!
實現步驟
完整的實現步驟需要如下幾步:
?
預先加載三個網絡模型
打開攝像頭視頻流/加載圖像
對每一幀進行人臉檢測
- 對檢測到的人臉進行性別與年齡預測
- 解析預測結果
- 顯示結果
?
代碼實現詳解
加載模型
MODEL_MEAN_VALUES?=?(78.4263377603,?87.7689143744,?114.895847746) ageList?=?['(0-2)',?'(4-6)',?'(8-12)',?'(15-20)',?'(25-32)',?'(38-43)',?'(48-53)',?'(60-100)'] genderList?=?['Male',?'Female']#?Load?network ageNet?=?cv.dnn.readNet(ageModel,?ageProto) genderNet?=?cv.dnn.readNet(genderModel,?genderProto) faceNet?=?cv.dnn.readNet(faceModel,?faceProto)?
人臉檢測
frameOpencvDnn?=?frame.copy()frameHeight?=?frameOpencvDnn.shape[0]frameWidth?=?frameOpencvDnn.shape[1]blob?=?cv.dnn.blobFromImage(frameOpencvDnn,?1.0,?(300,?300),?[104,?117,?123],?True,?False)net.setInput(blob)detections?=?net.forward()bboxes?=?[]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)bboxes.append([x1,?y1,?x2,?y2])cv.rectangle(frameOpencvDnn,?(x1,?y1),?(x2,?y2),?(0,?255,?0),?int(round(frameHeight/150)),?8)?
性別與年齡預測
????for?bbox?in?bboxes:#?print(bbox)face?=?frame[max(0,bbox[1]-padding):min(bbox[3]+padding,frame.shape[0]-1),max(0,bbox[0]-padding):min(bbox[2]+padding,?frame.shape[1]-1)]blob?=?cv.dnn.blobFromImage(face,?1.0,?(227,?227),?MODEL_MEAN_VALUES,?swapRB=False)genderNet.setInput(blob)genderPreds?=?genderNet.forward()gender?=?genderList[genderPreds[0].argmax()]#?print("Gender?Output?:?{}".format(genderPreds))print("Gender?:?{},?conf?=?{:.3f}".format(gender,?genderPreds[0].max()))ageNet.setInput(blob)agePreds?=?ageNet.forward()age?=?ageList[agePreds[0].argmax()]print("Age?Output?:?{}".format(agePreds))print("Age?:?{},?conf?=?{:.3f}".format(age,?agePreds[0].max()))label?=?"{},{}".format(gender,?age)cv.putText(frameFace,?label,?(bbox[0],?bbox[1]-10),?cv.FONT_HERSHEY_SIMPLEX,?0.8,?(0,?255,?255),?2,?cv.LINE_AA)cv.imshow("Age?Gender?Demo",?frameFace)print("time?:?{:.3f}?ms".format(time.time()?-?t))?
運行效果(看到這個預測,我又相信技術了!@_@):
完整源代碼:
import?cv2?as?cv import?timedef?getFaceBox(net,?frame,?conf_threshold=0.7):frameOpencvDnn?=?frame.copy()frameHeight?=?frameOpencvDnn.shape[0]frameWidth?=?frameOpencvDnn.shape[1]blob?=?cv.dnn.blobFromImage(frameOpencvDnn,?1.0,?(300,?300),?[104,?117,?123],?True,?False)net.setInput(blob)detections?=?net.forward()bboxes?=?[]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)bboxes.append([x1,?y1,?x2,?y2])cv.rectangle(frameOpencvDnn,?(x1,?y1),?(x2,?y2),?(0,?255,?0),?int(round(frameHeight/150)),?8)return?frameOpencvDnn,?bboxesfaceProto?=?"D:/projects/opencv_tutorial/data/models/face_detector/opencv_face_detector.pbtxt" faceModel?=?"D:/projects/opencv_tutorial/data/models/face_detector/opencv_face_detector_uint8.pb"ageProto?=?"D:/projects/opencv_tutorial/data/models/cnn_age_gender_models/age_deploy.prototxt" ageModel?=?"D:/projects/opencv_tutorial/data/models/cnn_age_gender_models/age_net.caffemodel"genderProto?=?"D:/projects/opencv_tutorial/data/models/cnn_age_gender_models/gender_deploy.prototxt" genderModel?=?"D:/projects/opencv_tutorial/data/models/cnn_age_gender_models/gender_net.caffemodel"MODEL_MEAN_VALUES?=?(78.4263377603,?87.7689143744,?114.895847746) ageList?=?['(0-2)',?'(4-6)',?'(8-12)',?'(15-20)',?'(25-32)',?'(38-43)',?'(48-53)',?'(60-100)'] genderList?=?['Male',?'Female']#?Load?network ageNet?=?cv.dnn.readNet(ageModel,?ageProto) genderNet?=?cv.dnn.readNet(genderModel,?genderProto) faceNet?=?cv.dnn.readNet(faceModel,?faceProto)#?Open?a?video?file?or?an?image?file?or?a?camera?stream cap?=?cv.VideoCapture(0) padding?=?20 while?cv.waitKey(1)?<?0:#?Read?framet?=?time.time()hasFrame,?frame?=?cap.read()frame?=?cv.flip(frame,?1)if?not?hasFrame:cv.waitKey()breakframeFace,?bboxes?=?getFaceBox(faceNet,?frame)if?not?bboxes:print("No?face?Detected,?Checking?next?frame")continuefor?bbox?in?bboxes:#?print(bbox)face?=?frame[max(0,bbox[1]-padding):min(bbox[3]+padding,frame.shape[0]-1),max(0,bbox[0]-padding):min(bbox[2]+padding,?frame.shape[1]-1)]blob?=?cv.dnn.blobFromImage(face,?1.0,?(227,?227),?MODEL_MEAN_VALUES,?swapRB=False)genderNet.setInput(blob)genderPreds?=?genderNet.forward()gender?=?genderList[genderPreds[0].argmax()]#?print("Gender?Output?:?{}".format(genderPreds))print("Gender?:?{},?conf?=?{:.3f}".format(gender,?genderPreds[0].max()))ageNet.setInput(blob)agePreds?=?ageNet.forward()age?=?ageList[agePreds[0].argmax()]print("Age?Output?:?{}".format(agePreds))print("Age?:?{},?conf?=?{:.3f}".format(age,?agePreds[0].max()))label?=?"{},{}".format(gender,?age)cv.putText(frameFace,?label,?(bbox[0],?bbox[1]-10),?cv.FONT_HERSHEY_SIMPLEX,?0.8,?(0,?255,?255),?2,?cv.LINE_AA)cv.imshow("Age?Gender?Demo",?frameFace)print("time?:?{:.3f}?ms".format(time.time()?-?t))任何程序錯誤,以及技術疑問或需要解答的,請掃碼添加作者VX
?
源碼與模型下載地址
https://github.com/xiaobingchan/opencv_tutorial
?
總結
以上是生活随笔為你收集整理的Opencv dnn实现人类性别检测和年龄预测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第五章数据库完整性
- 下一篇: python回测量化交易策略收益率