关于人脸识别,大家入门opencv,最常见的是用opencv级联分类器器里面的函数进行人脸的识别(当然里面包含很多各种物体的分类器,大家可以一一测试),今天我们来练一下关于人脸识别的级联器。
1,opencv +Haar Cascade(人脸检测)
①首先要找到人脸检测级联器的xml文件,打开你的电脑,在你安装的python-opencv的库里面,打开data文件,就可以看到很多级联器的xml文件,选择自己要用的文件,给复制到python文件的同一目录下:
②运行脚本文件.py进行人脸检测(摄像头或者视频下检测)
-
import cv2
-
video=cv2.VideoCapture(
0)
#打开摄像头
-
face_fea=cv2.CascadeClassifier(
'haarcascade_frontalface_alt.xml')
#用级联器打开人脸特征识别算法
-
while
True:
#while True 语句中一定要有结束该循环的break语句,否则会一直循环下去的。
-
open,image=video.read()
-
if
not
open:
-
print(
'视频结束')
-
break
-
#图片灰度化
-
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
-
face=face_fea.detectMultiScale(gray)
-
for x,y,w,h
in face:
-
cv2.rectangle(image,pt1=(x,y),pt2=(x+w,y+h),color=[
0,
0,
255],thickness=
2)
-
frame = cv2.flip(image,
1)
# 摄像头是和人对立的,将图像左右调换回来正常显示。
-
cv2.imshow(
'image',frame)
-
key=cv2.waitKey(
1000//
24)
-
if key==
ord(
'q'):
#q的啊克斯吗
-
print(
'用户达到自己的需要')
-
break
-
cv2.destroyAllWindows()
-
video.release()
#释放摄像头资源
就可以检测到人脸图像:
③当然也可以检测图片上的人脸了,运行脚本:
-
import cv2
-
image=cv2.imread(
'222.jpg')
-
image=cv2.resize(image,(
600,
800))
-
face_fea=cv2.CascadeClassifier(
'haarcascade_frontalface_alt.xml')
#用级联器打开人脸特征识别算法
-
#图片灰度化
-
gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
-
face=face_fea.detectMultiScale(gray)
-
for x,y,w,h
in face:
-
cv2.rectangle(image,pt1=(x,y),pt2=(x+w,y+h),color=[
0,
0,
255],thickness=
2)
-
cv2.imshow(
'image',image)
-
cv2.waitKey(
0)
运行结果:
2,opencv+DNN(结合了深度学习,backbone是resnet-10网络),其实算法源自于一篇SSD论文,有兴趣的可以去拜阅。
里面的权重文件下载地址:
https://github.com/61a6d591-1197-4b21-8b78-bce27de63399
①实现对图片的检测
-
import numpy
as np
-
import cv2, os
-
def
show_detections(
image, detections):
-
h, w, c = image.shape
-
#里面包含了人脸框的信息,还有置信度,分类等指标
-
for i
in
range(
0, detections.shape[
2]):
-
confidence = detections[
0,
0, i,
2]
-
if confidence >
0.6:
#置信度
-
box = detections[
0,
0, i,
3:
7] * np.array([w, h, w, h])
-
(startX, startY, endX, endY) = box.astype(
"int")
-
y = startY -
10
if startY -
10 >
10
else startY +
10
-
cv2.rectangle(image, (startX, startY), (endX, endY),(
0,
255,
0),
1)
-
cv2.putText(image,
"{:.2f}%".
format(confidence *
100), (startX, y),cv2.FONT_HERSHEY_SIMPLEX,
0.45, (
0,
255,
0),
2)
-
return image
-
def
detect_img(
net, image):
-
# 对图像进行预处理,减均值,图像缩小为(300,300),通道处理
-
blob = cv2.dnn.blobFromImage(image,
1.0, (
300,
300), (
104.0,
177.0,
123.0),
False,
False)
-
#输入给网络模型,进行一次前向传播
-
net.setInput(blob)
-
detections = net.forward()
-
return show_detections(image, detections)
-
#图片
-
def
test_file(
net, filepath):
-
img = cv2.imread(filepath)
-
showimg = detect_img(net, img)
-
cv2.imshow(
"img", showimg)
-
cv2.waitKey(
0)
-
net = cv2.dnn.readNetFromCaffe(
"deploy.prototxt",
"res10_300x300_ssd_iter_140000_fp16.caffemodel")
-
test_file(net,
'R-C.jpg')
运行结果:
②实现对视频的人脸检测:(可以选取自己喜欢的视频放进去检测)
-
import numpy
as np
-
import cv2, os
-
def
show_detections(
image, detections):
-
h, w, c = image.shape
-
#里面包含了人脸框的信息,还有置信度,分类等指标
-
for i
in
range(
0, detections.shape[
2]):
-
confidence = detections[
0,
0, i,
2]
-
if confidence >
0.6:
#置信度
-
box = detections[
0,
0, i,
3:
7] * np.array([w, h, w, h])
-
(startX, startY, endX, endY) = box.astype(
"int")
-
y = startY -
10
if startY -
10 >
10
else startY +
10
-
cv2.rectangle(image, (startX, startY), (endX, endY),(
0,
255,
0),
1)
-
cv2.putText(image,
"{:.2f}%".
format(confidence *
100), (startX, y),cv2.FONT_HERSHEY_SIMPLEX,
0.45, (
0,
255,
0),
2)
-
return image
-
def
detect_img(
net, image):
-
# 对图像进行预处理,减均值,图像缩小为(300,300),通道处理
-
blob = cv2.dnn.blobFromImage(image,
1.0, (
300,
300), (
104.0,
177.0,
123.0),
False,
False)
-
#输入给网络模型,进行一次前向传播
-
net.setInput(blob)
-
detections = net.forward()
-
return show_detections(image, detections)
-
#视频或者摄像头
-
def
test_camera(
net,filepath):
-
cap = cv2.VideoCapture(filepath)
-
while
True:
-
ret, img = cap.read()
-
if
not ret:
-
break
-
showimg = detect_img(net, img)
-
cv2.imshow(
"img", showimg)
-
cv2.waitKey(
1)
-
net = cv2.dnn.readNetFromCaffe(
"deploy.prototxt",
"res10_300x300_ssd_iter_140000_fp16.caffemodel")
-
test_camera(net,
'20220919214835.mp4')
-
3,Dlib人脸检测,并返回68个坐标点。
权重文件:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
-
#这个代码负责把图片进行68个特征点的提取,然后将关键点制作成txt文件。
-
import numpy
as np
-
import cv2
-
import dlib
-
#DLIB官网下载的68个特征点的训练模型文件
-
#人脸检测模型
-
detector=dlib.get_frontal_face_detector()
-
#正脸68个关键点检测模型
-
predictor = dlib.shape_predictor(
'shape_predictor_68_face_landmarks.dat')
-
#face_descriptor=dlib.face_recognition_model_v1('dlib_face_recognition_resnet_model_v1.dat')
-
# cv2读取图像
-
img = cv2.imread(
"223.jpg")
-
print(img)
-
# 取灰度
-
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
-
# 人脸数rects
-
rects = detector(img_gray,
1)
-
for i
in
range(
len(rects)):
-
landmarks = np.matrix([[p.x, p.y]
for p
in predictor(img,rects[i]).parts()])
#对坐标进行遍历
-
for idx, point
in
enumerate(landmarks):
-
# 68点的坐标
-
pos = (point[
0,
0], point[
0,
1])
-
print(idx,pos)
-
#利用cv2.circle给每个特征点画一个圈,共68个
-
cv2.circle(img, pos,
2, color=(
0,
255,
0))
-
#利用cv2.putText输出1-68
-
font = cv2.FONT_HERSHEY_SIMPLEX
-
cv2.putText(img,
str(idx+
1), pos, font,
0.8, (
0,
0,
255),
1,cv2.LINE_AA)
-
cv2.namedWindow(
"img",
2)
-
cv2.imshow(
"img", img)
-
cv2.waitKey(
0)
-
cv2.destroyAllWindows()
-
运行结果;
如果做人脸特征点检测,需要训练自己的人脸数据,不想手动标注文件这么麻烦的话,我觉得可以用这个dlib的68关键点检测对自己的数据进行打标处理。
转载:https://blog.csdn.net/Superman980527/article/details/128291578
查看评论