访问请移步至(David’s Wikipedia) https://www.qingdujun.com/ ,这里有能“击穿”平行宇宙的乱序并行字节流…
本文包括两部分:人脸检测、人脸识别。其中人脸检测主要采用了Haar级联分类器,采用Eigenfaces算法实现了人脸识别。
注:环境为OpenCV3与Python3.6。
目录:
首先,看下Haar级联分类器,Haar特征都描述了相邻图像区域的对比模式。例如,边、顶点和细线都能生成具有判别性的特征。
OpenCV3有个data/haarcascades
文件夹,包含了所有OpenCV的人脸检测XML文件。
detectMultiScale(gray,
1.3, # scaleFactor图像的压缩率
5 # minNeighbors人脸矩形保留近邻数目的最小值
)
根据检测结果,可以看到,OpenCV人脸检测效果好像并不太好。
OpenCV自带的haarcascade_frontalface_default.xml
,在cv2/data/
目录下能找到,或者直接使用EveryThing类似的检索工具磁盘检索一下。
static_face_detect.py
# -*- coding: utf-8 -*-
import cv2
def detect(filename):
face_cascade = cv2.CascadeClassifier(
r'C:\AppInstall\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
img = cv2.imread(filename)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray,1.3,5)
for (x,y,w,h) in faces:
img = cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0),2)
cv2.namedWindow('Person Detected!')
cv2.imshow('Person Detected!',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
if __name__ == '__main__':
detect(r'C:\Users\qingdujun\Desktop\huge.jpg')
视频流实时检测与静态图片技术差不多,只不过多了一个视频帧读取的过程。当然,以下也检测了一下眼睛的位置。
video_face_detect.py
# -*- coding: utf-8 -*-
import cv2
def detect():
face_cascade = cv2.CascadeClassifier(
r'C:\AppInstall\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier(
r'C:\AppInstall\Anaconda3\Lib\site-packages\cv2\data\haarcascade_eye.xml')
camera = cv2.VideoCapture(0)
while(True):
ret,frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#检测人脸
faces = face_cascade.detectMultiScale(gray, 1.3,5)
for(x,y,w,h) in faces:
cv2.rectangle(frame, (x,y), (x+w, y+h), (255,0,0),2)
#检测眼睛
eyes = eye_cascade.detectMultiScale(gray,1.3,5)
for (ex,ey,ew,eh) in eyes:
cv2.rectangle(frame, (ex,ey),(ex+ew,ey+eh),(0,255,0),2)
cv2.imshow('camera',frame)
if cv2.waitKey(1000//12) & 0xff == ord('q'):
break
camera.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
detect()
OpenCV3 有三种人脸识别 的方法,它们分别是:
以下演示一下Eigenfaces算法。其他算法只需要修改一下model即可,当然也需要一些小调整。
提示:Windows下,如果使用pip install opencv-python
安装OpenCV可能会cv2.face找不到,需要使用pip install opencv-contrib-python
重新安装。
采集不同人脸时,注意修改cv2.imwrite(r'./data/at/David/%s.pgm' % str(count), f)
此处的名称David
。
generate_face_from_video.py
# -*- coding: utf-8 -*-
import cv2
def generate():
face_cascade = cv2.CascadeClassifier(
r'C:\AppInstall\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
camera = cv2.VideoCapture(0)
count = 0
while (True):
ret, frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 检测人脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2)
f = cv2.resize(gray[y: y+h, x:x+w], (200, 200))
cv2.imwrite(r'./data/at/David/%s.pgm' % str(count), f)
count += 1
cv2.imshow("camera", frame)
if cv2.waitKey(1000 // 12) & 0xff == ord("q"):
break
camera.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
generate()
你应该先创建好文件夹,按照下图目录格式。
首先,载入图片并将其与Label一一对应。比如,读取David
文件夹时,c=0
不变化,当读取第二个人脸所在文件夹时c+1
,以此类推,最终将c作为下标,显示names[]
值。人脸识别包括两个过程,
在main中,你应该传入路径r'./data/at/'
,read_images函数才能正常运行。
face_recognition.py
# -*- coding: utf-8 -*-
import cv2,os,sys
import numpy as np
def read_images(path, sz = None):
c = 0
X, y = [], []
for dirname, dirnames, filenames in os.walk(path):
for subdirname in dirnames:
subject_path = os.path.join(dirname, subdirname)#./data/at/*
for filename in os.listdir(subject_path):
try:
if not filename.endswith('.pgm'):
continue
filepath = os.path.join(subject_path, filename)
im = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE)
if sz is not None:
im = cv2.resize(im,(200,200))
X.append(np.asarray(im, dtype=np.uint8))
y.append(c)
except:
print("Unexpected error:",sys.exc_info()[0])
c = c + 1
return [X, y]
def face_rec(img_path):
names = ['David','Guan-h','Type-q']
[X,y] = read_images(img_path)
y = np.asarray(y, dtype=np.int32)
model = cv2.face.EigenFaceRecognizer_create()
# model = cv2.face.EigenFaceRecognizer()
#pip install opencv-contrib-python
model.train(np.asarray(X), np.asarray(y))
camera = cv2.VideoCapture(0)
face_cascade = cv2.CascadeClassifier(
r'C:\AppInstall\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
while (True):
read, img = camera.read()
faces = face_cascade.detectMultiScale(img, 1.3, 5)
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
roi = gray[x: x+w, y: y+h]
try:
roi = cv2.resize(roi, (200, 200), interpolation=cv2.INTER_LINEAR)
params = model.predict(roi)
print("Label: %s, Confidence: %.2f" % (params[0], params[1]))
cv2.putText(img, names[params[0]], (x, y - 20), cv2.FONT_HERSHEY_SIMPLEX, 1, 255, 2)
except:
continue
cv2.imshow("camera", img)
if cv2.waitKey(1000 // 12) & 0xff == ord('q'):
break
cv2.destroyAllWindows()
if __name__ == "__main__":
face_rec(r'./data/at/')
References:
[1] 刘波[译]. OpenCV 3计算机视觉:Python语言实现(原书第2版)[M]. 北京:机械工业出版社, 2016.