结果如下图所示 。准确找到了人脸位置 。并绘制识别框 。右侧打印识别框和关键点信息 。
文章插图
文章插图
4. 编辑识别框 。保存人脸位置信息在这里我更加关注识别框的位置位置 。不太关心关键点的坐标信息 。因此接下来我们单独绘制识别框 。并把每一帧图像的人脸概率显示出来 。如果有同学更关注人脸关键点 。可以使用mediapipe的人脸网状检测 。能得到的关键点非常多 。这个我在后续章节也会写 。
因此 。接下来我们在上面代码的基础上继续补充 。detection.location_data.relative_bounding_box 获取检测框的左上角坐标和检测框的宽高 。保保存在bbox中 。如下我们可以看到识别框的信息都是归一化之后的 。需要将其转换为像素坐标 。
IN[21]:detection.location_data.relative_bounding_boxOut[21]:xmin:0.6636191606521606ymin:0.16451001167297363width:0.1620280146598816height:0.28804928064346313
转换方法也很简单 。只需要将比例长度x和w乘以实际图像宽度即可得到像素长度下的x和w 。同理y和h 。注意 。像素长度一定是整数 。如[200,200] 。比例长度是小数 。如[0.5, 0.5]
使用自定义矩形绘制函数cv2.rectangle() 。现在有了像素坐标下的左上坐标xy 。框的宽w和高h 。就可以在原图像img上把框绘制出来 。
detection.score 获取检测框的人脸概率值 。返回只有一个元素的列表 。detection.score[0] 提取这个元素 。返回浮点型数值 。
#导入人脸识别模块mpFace=mp.solutions.face_detection#导入绘图模块mpDraw=mp.solutions.drawing_utils#自定义人脸识别方法 。最小的人脸检测置信度0.5faceDetection=mpFace.FaceDetection(min_detection_confidence=0.5)#(1)导入视频filepath='C:\GameDownload\DeepLearning\face.mp4'cap=cv2.VideoCapture(filepath)pTime=0#记录每帧图像处理的起始时间boxlist=[]#保存每帧图像每个框的信息#(2)处理每一帧图像whileTrue:#每次取出一帧图像 。返回是否读取成功(True/False) 。以及读取的图像数据success,img=cap.read()#将opencv导入的BGR图像转为RGB图像imgRGB=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)#将每一帧图像传给人脸识别模块results=faceDetection.process(imgRGB)#如果检测不到人脸那就返回Noneifresults.detections:#返回人脸索引index(第几张脸) 。和关键点的坐标信息forindex,detectioninenumerate(results.detections):#遍历每一帧图像并打印结果#print(index,detection)#每帧图像返回一次是人脸的几率 。以及识别框的xywh 。后续返回关键点的xy坐标print(detection.score)#是人脸的的可能性print(detection.location_data.relative_bounding_box)#识别框的xywh#设置一个边界框 。接收所有的框的xywh及关键点信息bboxC=detection.location_data.relative_bounding_box#接收每一帧图像的宽、高、通道数ih,iw,ic=img.shape#将边界框的坐标点从比例坐标转换成像素坐标#将边界框的宽和高从比例长度转换为像素长度bbox=(int(bboxC.xmin*iw),int(bboxC.ymin*ih),int(bboxC.width*iw),int(bboxC.height*ih))#有了识别框的xywh就可以在每一帧图像上把框画出来cv2.rectangle(img,bbox,(255,0,0),5)#自定义绘制函数 。不适用官方的mpDraw.draw_detection#把人脸的概率显示在检测框上,img画板 。概率值*100保留两位小数变成百分数 。再变成字符串cv2.putText(img,f'{str(round(detection.score[0]*100,2))}%',(bbox[0],bbox[1]-20),#文本显示的位置 。-20是为了不和框重合cv2.FONT_HERSHEY_PLAIN,#文本字体类型2,(0,0,255),2)#字体大小;字体颜色;线条粗细#保存索引 。人脸概率 。识别框的x/y/w/hboxlist.append([index,detection.score,bbox])#记录每帧图像处理所花的时间cTime=time.time()fps=1/(cTime-pTime)#计算fps值pTime=cTime#更新每张图像处理的初始时间#把fps值显示在图像上,img画板;fps变成字符串;显示的位置;设置字体;字体大小;字体颜色;线条粗细cv2.putText(img,f'FPS:{str(int(fps))}',(10,50),cv2.FONT_HERSHEY_PLAIN,3,(0,255,0),3)#显示图像 。输入窗口名及图像数据cv2.imshow('image',img)ifcv2.waitKey(50)&0xFF==27:#每帧滞留50毫秒后消失 。ESC键退出break#释放视频资源cap.release()cv2.destroyAllWindows()
结果如下图所示 。右侧输出每帧图像的每个识别框的概率和框坐标
文章插图
文章插图
5. 优化识别框接下来把识别框做的好看一些 。只需要修改矩形框样式即可 。我们接着上面的代码编辑 。把识别框宽度调细一些 。在四个角上添加粗线段 。
推荐阅读
- 孩子从几岁开始识字比较合适?
- 到底是六七十年代的冬天冷,还是现在的冬天冷?
- 如何理解王阳明的“四句教”?“无善无恶是心之体,有善有恶是意之动,知善知恶是良知,为善去恶是格物”?
- 包包链条掉色怎么补救 包包链条褪色了怎么变新
- 六七十年代家里有20000块钱,算什么家庭?
- 小孩子现在学习的国学到底是什么?如果学校教授三从四德,你会同意吗?为什么?
- 五十、六十、七十年代出生的朋友,穿过手工做的布鞋吗?还记得是谁做的吗?
- 属虎的人性格怎么样?
- 好看的校园言情小说甜文 高质量甜宠文青春校园