1说明 1。1效果图 图片静态识别有bug 视频和摄像头识别,动态可变 1。2源代码来源:https:github。comspmallicklearnopencv 1。3对源代码进行修改、注释、增加,便于理解。 1。4模型文件来自,或者参考这里的源代码感谢作者,提供这两个模型:agenet。caffemodel和gendernet。caffemodelhttps:github。comRoggu123Algorithm解压后AlgorithmmasterPracticeCVFaceDetectionagegender下找到 2准备 2。1环境:python3。8opencv4。4。0深度deepinlinux操作系统微软编辑器vscode。 2。2文件结构: 3AgeGender。py代码 3。1第1步:导入模块importcv2importmath 3。2blobcv2。dnn。blobFromImage(image,scalefactor1。0,size,mean,swapRBTrue,cropFalse,ddepthCV32F) 参数 1。image,这是传入的,需要进行处理的图像。 2。scalefactor,执行完减均值后,需要缩放图像,默认是1。 3。size,这是神经网络,真正支持输入的值。 4。mean,这是我们要减去的均值,可以是R,G,B均值三元组,或者是一个值,每个通道都减这值。 如果执行减均值,通道顺序是R、G、B。如果,输入图像通道顺序是B、G、R,那么请确保swapRBTrue,交换通道。 5。swapRB,OpenCV认为图像通道顺序是B、G、R,而减均值时顺序是R、G、B, 为了解决这个矛盾,设置swapRBTrue即可。 6。crop,如果crop裁剪为真,则调整输入图像的大小,使调整大小后的一侧等于相应的尺寸,另一侧等于或大于。 然后,从中心进行裁剪。如果裁剪为假,则直接调整大小而不进行裁剪并保留纵横比。 第2步:获取脸部框函数defgetFaceBox(net,frame,confthreshold0。7):frameOpencvDnnframe。copy()frameHeightframeOpencvDnn。shape〔0〕frameWidthframeOpencvDnn。shape〔1〕关键参数blobcv2。dnn。blobFromImage(frameOpencvDnn,1。0,(300,300),〔104,117,123〕,True,False)net。setInput(blob)detectionsnet。forward()bboxes〔〕foriinrange(detections。shape〔2〕):confidencedetections〔0,0,i,2〕ifconfidenceconfthreshold:x1int(detections〔0,0,i,3〕frameWidth)y1int(detections〔0,0,i,4〕frameHeight)x2int(detections〔0,0,i,5〕frameWidth)y2int(detections〔0,0,i,6〕frameHeight)bboxes。append(〔x1,y1,x2,y2〕)cv2。rectangle(frameOpencvDnn,(x1,y1),(x2,y2),(0,255,0),int(round(frameHeight150)),8)returnframeOpencvDnn,bboxes 3。3主要是自己喜欢微软编辑器vscode,点击运行即可。第3步:路径管理,自己增加的importoscurpathos。path。realpath(file)获取当前AgeGender。py代码的绝对路径dirpathos。path。dirname(curpath)获取当前文件的文件夹路径 3。4第4步:现有的模型加载faceProtodirpathmodelopencvfacedetector。pbtxtfaceModeldirpathmodelopencvfacedetectoruint8。pbageProtodirpathmodelagedeploy。prototxtageModeldirpathmodelagenet。caffemodel自行下载genderProtodirpathmodelgenderdeploy。prototxtgenderModeldirpathmodelgendernet。caffemodel自行下载MODELMEANVALUES(78。4263377603,87。7689143744,114。895847746)ageList〔(02),(46),(812),(1520),(2532),(3843),(4853),(60100)〕genderList〔Male,Female〕Loadnetwork加载网络ageNetcv2。dnn。readNet(ageModel,ageProto)读取预训练模型genderNetcv2。dnn。readNet(genderModel,genderProto)faceNetcv2。dnn。readNet(faceModel,faceProto)padding20 3。5第5步:加载图片或者视频识别视频类capcv2。VideoCapture(0)摄像头识别capcv2。VideoCapture(dirpathv1。mp4)视频识别图片类常规是image,为了与视频代码兼容这里采用frame代替原来的imageframecv2。imread(dirpath3。jpeg) 3。6第6步:循环whilecv2。waitKey(1)0:图片识别时,可注释掉视频类hasFrame,framecap。read()ifnothasFrame:cv2。waitKey()break视频类frameFace,bboxesgetFaceBox(faceNet,frame)ifnotbboxes:continueforbboxinbboxes:faceframe〔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)〕blobcv2。dnn。blobFromImage(face,1。0,(227,227),MODELMEANVALUES,swapRBFalse)genderNet。setInput(blob)genderPredsgenderNet。forward()性别gendergenderList〔genderPreds〔0〕。argmax()〕ageNet。setInput(blob)agePredsageNet。forward()年龄ageageList〔agePreds〔0〕。argmax()〕label{},{}。format(gender,age)输出字体颜色:0,255,255黄色;0,0,255红色cv2。putText(frameFace,label,(bbox〔0〕,bbox〔1〕10),cv2。FONTHERSHEYSIMPLEX,0。8,(0,0,255),2,cv2。LINEAA)窗口展示cv2。imshow(AgeGenderDemo,frameFace) 4小结: 可能由于现有的模型,训练数据太少,导致可能出现bug。 可以自行训练数据集,训练好了自己再用这个套用,当然这是一件浩大的工程,提高识别精度。 一般人,玩玩技术知道怎么回事就可以了。 自己让代码运行起来,并加入相关代码,复习python相关知识(编程思维和路径管理)。 希望大家喜欢。