飞道的博客

关于人脸检测和人脸关键点检测的详解(涉及Opencv 和Dlibd)

640人阅读  评论(0)

关于人脸识别,大家入门opencv,最常见的是用opencv级联分类器器里面的函数进行人脸的识别(当然里面包含很多各种物体的分类器,大家可以一一测试),今天我们来练一下关于人脸识别的级联器。

1,opencv +Haar Cascade(人脸检测)

①首先要找到人脸检测级联器的xml文件,打开你的电脑,在你安装的python-opencv的库里面,打开data文件,就可以看到很多级联器的xml文件,选择自己要用的文件,给复制到python文件的同一目录下:

 ②运行脚本文件.py进行人脸检测(摄像头或者视频下检测)


  
  1. import cv2
  2. video=cv2.VideoCapture( 0) #打开摄像头
  3. face_fea=cv2.CascadeClassifier( 'haarcascade_frontalface_alt.xml') #用级联器打开人脸特征识别算法
  4. while True: #while True 语句中一定要有结束该循环的break语句,否则会一直循环下去的。
  5. open,image=video.read()
  6. if not open:
  7. print( '视频结束')
  8. break
  9. #图片灰度化
  10. gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  11. face=face_fea.detectMultiScale(gray)
  12. for x,y,w,h in face:
  13. cv2.rectangle(image,pt1=(x,y),pt2=(x+w,y+h),color=[ 0, 0, 255],thickness= 2)
  14. frame = cv2.flip(image, 1) # 摄像头是和人对立的,将图像左右调换回来正常显示。
  15. cv2.imshow( 'image',frame)
  16. key=cv2.waitKey( 1000// 24)
  17. if key== ord( 'q'): #q的啊克斯吗
  18. print( '用户达到自己的需要')
  19. break
  20. cv2.destroyAllWindows()
  21. video.release() #释放摄像头资源

就可以检测到人脸图像:

 ③当然也可以检测图片上的人脸了,运行脚本:


  
  1. import cv2
  2. image=cv2.imread( '222.jpg')
  3. image=cv2.resize(image,( 600, 800))
  4. face_fea=cv2.CascadeClassifier( 'haarcascade_frontalface_alt.xml') #用级联器打开人脸特征识别算法
  5. #图片灰度化
  6. gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
  7. face=face_fea.detectMultiScale(gray)
  8. for x,y,w,h in face:
  9. cv2.rectangle(image,pt1=(x,y),pt2=(x+w,y+h),color=[ 0, 0, 255],thickness= 2)
  10. cv2.imshow( 'image',image)
  11. cv2.waitKey( 0)

运行结果:

 2,opencv+DNN(结合了深度学习,backbone是resnet-10网络),其实算法源自于一篇SSD论文,有兴趣的可以去拜阅。

里面的权重文件下载地址:

https://github.com/61a6d591-1197-4b21-8b78-bce27de63399

OpenCV/opencv_3rdparty at dnn_samples_face_detector_20180205_fp16 (github.com)https://github.com/opencv/opencv_3rdparty/tree/dnn_samples_face_detector_20180205_fp16

①实现对图片的检测


  
  1. import numpy as np
  2. import cv2, os
  3. def show_detections( image, detections):
  4. h, w, c = image.shape
  5. #里面包含了人脸框的信息,还有置信度,分类等指标
  6. for i in range( 0, detections.shape[ 2]):
  7. confidence = detections[ 0, 0, i, 2]
  8. if confidence > 0.6: #置信度
  9. box = detections[ 0, 0, i, 3: 7] * np.array([w, h, w, h])
  10. (startX, startY, endX, endY) = box.astype( "int")
  11. y = startY - 10 if startY - 10 > 10 else startY + 10
  12. cv2.rectangle(image, (startX, startY), (endX, endY),( 0, 255, 0), 1)
  13. cv2.putText(image, "{:.2f}%". format(confidence * 100), (startX, y),cv2.FONT_HERSHEY_SIMPLEX, 0.45, ( 0, 255, 0), 2)
  14. return image
  15. def detect_img( net, image):
  16. # 对图像进行预处理,减均值,图像缩小为(300,300),通道处理
  17. blob = cv2.dnn.blobFromImage(image, 1.0, ( 300, 300), ( 104.0, 177.0, 123.0), False, False)
  18. #输入给网络模型,进行一次前向传播
  19. net.setInput(blob)
  20. detections = net.forward()
  21. return show_detections(image, detections)
  22. #图片
  23. def test_file( net, filepath):
  24. img = cv2.imread(filepath)
  25. showimg = detect_img(net, img)
  26. cv2.imshow( "img", showimg)
  27. cv2.waitKey( 0)
  28. net = cv2.dnn.readNetFromCaffe( "deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
  29. test_file(net, 'R-C.jpg')

运行结果:

 ②实现对视频的人脸检测:(可以选取自己喜欢的视频放进去检测)


  
  1. import numpy as np
  2. import cv2, os
  3. def show_detections( image, detections):
  4. h, w, c = image.shape
  5. #里面包含了人脸框的信息,还有置信度,分类等指标
  6. for i in range( 0, detections.shape[ 2]):
  7. confidence = detections[ 0, 0, i, 2]
  8. if confidence > 0.6: #置信度
  9. box = detections[ 0, 0, i, 3: 7] * np.array([w, h, w, h])
  10. (startX, startY, endX, endY) = box.astype( "int")
  11. y = startY - 10 if startY - 10 > 10 else startY + 10
  12. cv2.rectangle(image, (startX, startY), (endX, endY),( 0, 255, 0), 1)
  13. cv2.putText(image, "{:.2f}%". format(confidence * 100), (startX, y),cv2.FONT_HERSHEY_SIMPLEX, 0.45, ( 0, 255, 0), 2)
  14. return image
  15. def detect_img( net, image):
  16. # 对图像进行预处理,减均值,图像缩小为(300,300),通道处理
  17. blob = cv2.dnn.blobFromImage(image, 1.0, ( 300, 300), ( 104.0, 177.0, 123.0), False, False)
  18. #输入给网络模型,进行一次前向传播
  19. net.setInput(blob)
  20. detections = net.forward()
  21. return show_detections(image, detections)
  22. #视频或者摄像头
  23. def test_camera( net,filepath):
  24. cap = cv2.VideoCapture(filepath)
  25. while True:
  26. ret, img = cap.read()
  27. if not ret:
  28. break
  29. showimg = detect_img(net, img)
  30. cv2.imshow( "img", showimg)
  31. cv2.waitKey( 1)
  32. net = cv2.dnn.readNetFromCaffe( "deploy.prototxt", "res10_300x300_ssd_iter_140000_fp16.caffemodel")
  33. test_camera(net, '20220919214835.mp4')

3,Dlib人脸检测,并返回68个坐标点。

权重文件:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2


  
  1. #这个代码负责把图片进行68个特征点的提取,然后将关键点制作成txt文件。
  2. import numpy as np
  3. import cv2
  4. import dlib
  5. #DLIB官网下载的68个特征点的训练模型文件
  6. #人脸检测模型
  7. detector=dlib.get_frontal_face_detector()
  8. #正脸68个关键点检测模型
  9. predictor = dlib.shape_predictor( 'shape_predictor_68_face_landmarks.dat')
  10. #face_descriptor=dlib.face_recognition_model_v1('dlib_face_recognition_resnet_model_v1.dat')
  11. # cv2读取图像
  12. img = cv2.imread( "223.jpg")
  13. print(img)
  14. # 取灰度
  15. img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
  16. # 人脸数rects
  17. rects = detector(img_gray, 1)
  18. for i in range( len(rects)):
  19. landmarks = np.matrix([[p.x, p.y] for p in predictor(img,rects[i]).parts()]) #对坐标进行遍历
  20. for idx, point in enumerate(landmarks):
  21. # 68点的坐标
  22. pos = (point[ 0, 0], point[ 0, 1])
  23. print(idx,pos)
  24. #利用cv2.circle给每个特征点画一个圈,共68个
  25. cv2.circle(img, pos, 2, color=( 0, 255, 0))
  26. #利用cv2.putText输出1-68
  27. font = cv2.FONT_HERSHEY_SIMPLEX
  28. cv2.putText(img, str(idx+ 1), pos, font, 0.8, ( 0, 0, 255), 1,cv2.LINE_AA)
  29. cv2.namedWindow( "img", 2)
  30. cv2.imshow( "img", img)
  31. cv2.waitKey( 0)
  32. cv2.destroyAllWindows()

运行结果;

 

如果做人脸特征点检测,需要训练自己的人脸数据,不想手动标注文件这么麻烦的话,我觉得可以用这个dlib的68关键点检测对自己的数据进行打标处理。


转载:https://blog.csdn.net/Superman980527/article/details/128291578
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场