写在前面的话 基于dlib库的模型,实现人脸识别和焦点人物的检测。最后呈现的效果为焦点人物的识别框颜色与其他人物框不一样。
准备工作
需要安装好python环境,安装好dlib、opencv-python库等,具体可以看报错信息(可以使用PyCharm来运行和编辑py文件),然后把需要的库补全,文章最后会有完整代码,但是需要与shape_predictor_68_face_landmarks.dat模型文件同处一个路径下,然后启用。(百度可以下载到)
设计过程
- 因为是在自己电脑完成的必做题设计,所以前期还经历了相应的Python安装与环境配置,相应的资源库安装,例如dlib、opencv-python等等。
- 然后运行综合了(68个人脸特征点检测模型完成静止图像的人脸检测与标注)和(完成实时摄制视频的人脸检测与定位)的参考文件opencv_webcam_face_detection.py,发现可以实现实时视频的人脸检测。
- 对参考文件的代码进行分析,理解每一句代码的意思。对比查找设计需要的功能模块,实现1280x720视频输出,实现类win10相机的焦点人物识别。
- 上网查找并学习相应资料,参考win10相机的算法,创建自己的基于距离与面积的焦点人物算法,根据自己的需要对源代码进行添加及修改。
- 最后对代码进行测试,且不断修改成最适合的版本。
Python程序
流程图
焦点人物算法
内在逻辑:模仿win10相机,当有多于1个人时,优先选择最居中的为焦点人物,但若在其他地方的人脸面积大于4倍中心的人脸面积,则选择其他地方的作为焦点人物。
实际代码
import dlib
import cv2
import math
cam = cv2.VideoCapture(0)
cam.set(3, 1280)
cam.set(4, 720)
color_focus = (255, 0, 255)
color_other = (255, 255, 255)
lineWidth_focus = 2
lineWidth_other = 1
w = cam.get(3) / 2
h = cam.get(4) / 2
d_center = 10000
index_center = 0
index_area = 0
area_center = -1
area = -1
detector = dlib.get_frontal_face_detector()
predictor_path = "shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(predictor_path)
while True:
ret_val, img = cam.read()
rgb_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
faces = detector(rgb_image)
for i, det in enumerate(faces):
d = math.sqrt((w-(det.left()+(det.right()-det.left())/2))**2+(h-(det.top()+(det.bottom()-det.top())/2))**2)
if d < d_center:
index_center = i
d_center = d
area_center = abs((det.right() - det.left()) * (det.bottom() - det.top()))
for i, det in enumerate(faces):
if abs((det.right() - det.left()) * (det.bottom() - det.top())) > area:
index_area = i
area = abs((det.right() - det.left()) * (det.bottom() - det.top()))
if area > 5*area_center:
index_center = index_area
for i, det in enumerate(faces):
if i == index_center:
print(d_center, i)
cv2.rectangle(img, (det.left(), det.top()), (det.right(), det.bottom()), color_focus, lineWidth_focus)
shape = predictor(img, det)
for p in shape.parts():
cv2.circle(img, (p.x, p.y), 2, (124, 252, 0), -1)
else:
cv2.rectangle(img, (det.left(), det.top()), (det.right(), det.bottom()), color_other, lineWidth_other)
shape = predictor(img, det)
for p in shape.parts():
cv2.circle(img, (p.x, p.y), 2, (255, 255, 255), -1)
cv2.imshow('my webcam', img)
if cv2.waitKey(1) == 27:
break
cv2.destroyAllWindows()
运行情况
为了容易分辨焦点人物与其他人物,首先将焦点人物框的宽度设为2,颜色设为紫红色,68个识别点设为茶绿色;其他人物框的宽度设为1,颜色设为白色,68个识别点设为白色。 然后进行多次测试,通过整理测试结果,发现算法没有错误,焦点人物按照距离和面积两个因素来决定。成功运行图如下: 不展示图了,但是主人物为紫红框,其他人物为白色圈。与预期一致。
如果能给你提供一点帮助,希望你能点个赞,谢谢。
|