本文总结了opencv中的Haar Cascades和face_recognition,以及旷视face++接口3种人脸检测方法。
旷视face++的API文档地址:https://console.faceplusplus.com.cn/documents/4888373
face_recognition项目地址:https://github.com/ageitgey/face_recognition
face_recognition官方推荐Linux或者macOS环境,经过验证在win10下也可以运行,环境如下:
- python3.6.7
- pip install opencv-python,opencv4.0.1.23
- pip install dlib,dlib19.7.0
- pip install face_recognition,face_recognition1.2.3
1、使用opencv中的Haar Cascades检测人脸位置
# -*- coding:utf-8 -*-
import cv2
img_path = "..\\data\\imgs\\solvay.jpg"
pathf = "haarcascade_frontalface_default.xml"
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
face_cascade.load(pathf)
im = cv2.imread(img_path)
face_ = face_cascade.detectMultiScale(im,
scaleFactor=1.1,
minNeighbors=10,
flags=0|cv2.CASCADE_SCALE_IMAGE,
minSize=(1,1))
cv2.namedWindow("result",cv2.WINDOW_NORMAL)
for _ in face_:
lt = (_[0],_[1])
rb = (_[0]+_[2],_[1]+_[3])
cv2.rectangle(im,lt,rb,(0,200,0),2)
cv2.imshow("result",im)
cv2.imwrite("..\\data\\imgs\\solvay_harr.jpg",im)
cv2.waitKey(0)
代码中的haarcascade_frontalface_default.xml可以在opencv的安装目录中找到,detectMultiScale方法的主要参数有5个,其中scaleFactor应该大于1,否则程序会报错,经过调参发现minNeighbors对最终结果影响较为明显,minNeighbors值较小会导致误检率增加,最终的结果如下图所示。
从上图可以看到右侧的两个人(应该是威尔逊和福勒)没有被识别出来。下面使用face_recognition来进行检测。
2、使用face_recognition检测人脸位置
# -*- coding:utf-8 -*-
import cv2
import face_recognition
img_path = "..\\data\\imgs\\solvay.jpg"
im_fr = face_recognition.load_image_file(img_path)
face_ = face_recognition.face_locations(im_fr,number_of_times_to_upsample=1,model="cnn")
print(face_)
im = cv2.imread(img_path)
print("img size ",im.shape)
cv2.namedWindow("result",cv2.WINDOW_NORMAL)
for _ in face_:
top, right, bottom, left = _
cv2.rectangle(im,(left, top), (right, bottom),(0,200,0),2)
cv2.imshow("result",im)
cv2.imwrite("..\\data\\imgs\\solvay_cnn.jpg",im)
cv2.waitKey(0)
face_recognition中检测出来的人脸位置坐标数组和opencv中的数组含义不一样,差异如下:
- opencv中为 [left_top_x,left_top_y,width,height]
- face_recognition中为 [left_top_y,right_bottom_x,right_bottom_y,left_top_x]
所以在用cv2.rectangle画矩形框的时候代码有些不同。检测结果如下图所示,从图中可以看出所有的人脸都被检测出来了。
以上两种方法的比较
- 检测效果:face_recogniton是基于cnn实现的检测,调参简单(本例中使用了默认参数number_of_times_to_upsample=1),效果比较好。相对而言Haar Cascades可调的参数多,而且效果比较差,边缘部分的人脸没有识别出来。
- 计算速度:本例是在单cpu上进行的计算,从计算速度来看,Haar Cascades远远快于face_recogniton。
3、Face++接口
Face++注册帐号之后就可以免费使用API,API文档地址 https://console.faceplusplus.com.cn/documents/4888373
下面的代码使用Detect API检测人脸
import requests
from json import JSONDecoder
import cv2
http_url ="https://api-cn.faceplusplus.com/facepp/v3/detect"
# 下面的key和secret是在Face++中创建api key获取的
key =""
secret =""
img_path ="./solvay.jpg"
data = {"api_key":key, "api_secret": secret}
img = {"image_file": open(img_path, "rb")}
response = requests.post(http_url, data=data, files=img)
req_con = response.content.decode('utf-8')
req_dict = JSONDecoder().decode(req_con)
face_counts = len(req_dict["faces"])
print("检测出人脸数量: ",face_counts)
im = cv2.imread(img_path)
for i in range(face_counts):
pos = req_dict["faces"][i]["face_rectangle"]
left = pos["left"]
top = pos["top"]
right = pos["left"]+pos["width"]
bottom = pos["top"]+pos["height"]
cv2.rectangle(im, (left, top), (right, bottom), color=(0,200,0),thickness=2)
cv2.namedWindow("",cv2.WINDOW_NORMAL)
cv2.imshow("",im)
cv2.waitKey(0)
下图是检测的结果