人脸检测技术,在深度学习之前,特征+分类器一直是最好的选择,dlib便是用hog特征+级联分类器实现了认脸的检测,它本身是用c++写的,但也有python接口。要看具体的文档可以到dlib官网,这里只实现一个简单的应用。这是一个认脸定位+是不是笑脸的分类的应用。使用dlib定位,使用sklearn的svm来完成分类,笑脸与不笑脸是预先训练的,数据得自行准备。准备笑脸的图放在smile文件夹下,不笑的图放在no smile文件夹下。
#python3.5
#windows
#author:gjc
import cv2
import dlib
import numpy as np
from sklearn import svm
import os
from PIL import Image
#获取默认摄像头
cap = cv2.VideoCapture(0)
#dlib加载68个点模型
detector=dlib.get_frontal_face_detector()
predictor_path = "shape_predictor_68_face_landmarks.dat"
predictor = dlib.shape_predictor(predictor_path)
data=[]
label=[]
#读取认脸已分类好的数据
def read(dir,l):
f=os.listdir(dir)
L=len(f)-1
for i in range(L):
imgdir=dir+str(f[i])
im=Image.open(imgdir)
#draw = ImageDraw.Draw(im)
dets=detector(np.array(im),0)
if len(dets)==0:
continue
facepoint = np.array([[p.x, p.y] for p in predictor(np.array(im), dets[0]).parts()])
arr=np.zeros((20,2))
for j in range(48,68):
#draw.arc((facepoint[j][0]-5, facepoint[j][1]-5, facepoint[j][0]+5, facepoint[j][1]+5), 0, 360, fill=(55,255,155))
arr[j-48][0]=facepoint[j][0]-facepoint[27][0]
arr[j-48][1]=facepoint[j][1]-facepoint[27][1]
arr=(arr-arr.min())/(arr.max()-arr.min())
data.append(arr.flatten())
label.append(l)
read("smile/",1)
read("nosmile/",0)
#用svm进行分类
clf = svm.SVC()
clf.fit(np.array(data), label)
while(1):
#读取摄像头图片
ret, frame = cap.read()
#定位
dets=detector(frame,0)
#画人脸的框
for i,d in enumerate(dets):
cv2.rectangle(frame, (int(d.left()), int(d.top())), (int(d.right()), int(d.bottom())), (0,255,0),2,0)
for i,d in enumerate(dets):
facepoint = np.array([[p.x, p.y] for p in predictor(frame, dets[i]).parts()])
#画68个点
for j in range(68):
#if facepoint[j][1]<640 and facepoint[j][0]<480:
#frame[facepoint[j][1]][facepoint[j][0]] = [0,0,0]
#cv2.line(frame,(facepoint[j][0],facepoint[j][1]),(facepoint[j+1][0],facepoint[j+1][1]),(155,155,155),2)
cv2.circle(frame,(facepoint[j][0],facepoint[j][1]),2,(55,255,155),2)
arr=np.zeros((20,2))
#读取特征点,归一化
for j in range(48,68):
arr[j-48][0]=facepoint[j][0]-facepoint[27][0]
arr[j-48][1]=facepoint[j][1]-facepoint[27][1]
arr=(arr-arr.min())/(arr.max()-arr.min())
#svm分类判断是否笑脸
if clf.decision_function(arr.flatten().reshape(1,-1))>0:
cv2.putText(frame, 'smile', (int(d.left()),int(d.top())), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255 ,0), thickness = 2, lineType = 8)
else:
cv2.putText(frame, 'No smile', (int(d.left()),int(d.top())), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 255 ,0), thickness = 2, lineType = 8)
#展示处理后的图片
cv2.imshow("capture", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
效果如下:

版权声明:本文为原创文章,转载请注明出处和作者,不得用于商业用途,请遵守
CC BY-NC-SA 4.0协议。
赞赏一下
支付宝打赏
微信打赏