基于opencv,face_recognition和Face++的人脸位置检测
本文总结了opencv中的Haar Cascades和face_recognition,以及旷视face++接口3种人脸检测方法。 旷视face++的API文档地址: 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文档地址 下面的代码使用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)
下图是检测的结果