是基于之前的博客写的,这次主要是把结果通过flask放到前端上
OpenCV/Dlib/face_recognition 人脸检测及人脸对齐_frostxxx的博客-CSDN博客_dlib face
文件夹框架:
要注意把要用来检测的图片放到static里,如果放在别的地方即使是绝对路径也调不到。detect和dlib的jpg是后来生成再调用的
人脸检测的具体代码就不展开说了,反正就是复制粘贴之前博客里的
图片的实现结果是
原图
结果图
(左边是opencv人脸检测结果,右边是dlib人脸对齐结果)
检测是否为同一个人
def index():
#根据文件路径和模型获取人脸特征向量
def load_known_faces(dstImgPath, mtcnn, resnet):
aligned = []
knownImg = cv2.imread(dstImgPath)
face = mtcnn(knownImg)
#使⽤mtcnn检测⼈脸,返回【⼈脸数组】
if face is not None:
aligned.append(face[0])
aligned = torch.stack(aligned).to(device)
with torch.no_grad():
known_faces_emb = resnet(aligned).detach().cpu()
#使⽤resnet模型 获取⼈脸对应的特征向量
return known_faces_emb, knownImg
def match_faces(faces_emb, known_faces_emb, threshold):
isExistDst = False
distance = (known_faces_emb[0] - faces_emb[0]).norm().item()
if(distance < threshold):
isExistDst = True
return isExistDst
device = torch.device('cuda:0' if torch.cuda.is_available() else'cpu')
#mtcnn模型加载【设置⽹络参数,进⾏⼈脸检测】
mtcnn = MTCNN(min_face_size=12, thresholds=[0.2, 0.2, 0.3],keep_all=True, device=device)
#InceptionResnetV1模型加载【⽤于获取⼈脸特征向量】
resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)
MatchThreshold = 0.8
print("matchThreshold:",MatchThreshold)
#⼈脸特征向量匹配阈值设置
pic1='static/海媛1.jpeg'
pic2='static/海媛2.jpeg'
known_faces_emb, _ = load_known_faces(pic1,mtcnn, resnet)
faces_emb, img = load_known_faces(pic2, mtcnn,
resnet)
#待检测⼈物图
isExistDst = match_faces(faces_emb, known_faces_emb, MatchThreshold)
#⼈脸匹配
if isExistDst:
boxes, prob, landmarks = mtcnn.detect(img, landmarks=True)
#返回⼈脸框,概率,5个⼈脸关键点
result='匹配,是同一个人'
else:
result='不匹配,不是同一个人'
d_path=detect(pic1)
b_path=dlib(pic2)
return render_template("index.html",result=result,pic1=pic1,pic2=pic2,d_path=d_path,b_path=b_path)
人脸检测部分,返回的是所存储图片的路径
def detect(filename):
face_cascade = cv2.CascadeClassifier(
'/Users/yangqianyi/Documents/Anaconda3/anaconda3/lib/python3.9/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.imshow('Person Detected!', img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
detect_path = "static/detect.jpg"
cv2.imwrite(detect_path, img)
return detect_path
人脸对齐部分,用到的模型是之前博客里的
def dlib(filename):
import cv2
import dlib
# 读取图⽚
img = cv2.imread(filename)
# 灰度化处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 获得脸部位置检测器
detector = dlib.get_frontal_face_detector()
# 初步⼈脸检测,框出矩形。返回值是<class 'dlib.dlib.rectangle'>,即⼀个矩形,表示 为能够唯⼀表示这个⼈脸矩形框两个点坐标:左上⻆(x1,y1)、右下⻆(x2,y2
dets = detector(gray, 1)
# 使⽤模型构建特征提取器,返回5/68个特征点的位置 #此处路径是⾃⼰的python路径下site-packages位置
predictor = dlib.shape_predictor(
r"/Users/yangqianyi/Documents/Anaconda3/anaconda3/lib/python3.9/site-packages/shape_predictor_68_face_landmarks.dat")
for face in dets:
shape = predictor(img, face)
for pt in shape.parts():
pt_pos = (pt.x, pt.y)
cv2.circle(img, pt_pos, 2, (0, 255, 0), 1)
# cv2.imshow("image", img)
dlib_path = "static/dlib.jpg"
cv2.imwrite(dlib_path, img)
return dlib_path
index.htm:
注意path要是相对路径,绝对路径图片无法显示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flask人脸检测</title>
</head>
<body>
<h1>人脸检测</h1>
<img src={{pic1}} height="300"/>
<img src={{pic2}} height="300"/>
<br>检测结果:{{result}}<br>
<img src={{d_path}} height="300"/>
<img src={{b_path}} height="300"/>
<br>以上为对齐结果<br>
</body>
</html>
最终运行结果:
进入http://127.0.0.1:5000显示网页如下:
附app.py全部代码:
from flask import Flask,render_template,request
import pymysql
import cv2
import torch
from facenet_pytorch import MTCNN,InceptionResnetV1
app=Flask(__name__)
@app.route('/')
def index():
#根据文件路径和模型获取人脸特征向量
def load_known_faces(dstImgPath, mtcnn, resnet):
aligned = []
knownImg = cv2.imread(dstImgPath)
face = mtcnn(knownImg)
#使⽤mtcnn检测⼈脸,返回【⼈脸数组】
if face is not None:
aligned.append(face[0])
aligned = torch.stack(aligned).to(device)
with torch.no_grad():
known_faces_emb = resnet(aligned).detach().cpu()
#使⽤resnet模型 获取⼈脸对应的特征向量
return known_faces_emb, knownImg
def match_faces(faces_emb, known_faces_emb, threshold):
isExistDst = False
distance = (known_faces_emb[0] - faces_emb[0]).norm().item()
if(distance < threshold):
isExistDst = True
return isExistDst
device = torch.device('cuda:0' if torch.cuda.is_available() else'cpu')
#mtcnn模型加载【设置⽹络参数,进⾏⼈脸检测】
mtcnn = MTCNN(min_face_size=12, thresholds=[0.2, 0.2, 0.3],keep_all=True, device=device)
#InceptionResnetV1模型加载【⽤于获取⼈脸特征向量】
resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)
MatchThreshold = 0.8
print("matchThreshold:",MatchThreshold)
#⼈脸特征向量匹配阈值设置
pic1='static/海媛1.jpeg'
pic2='static/海媛2.jpeg'
known_faces_emb, _ = load_known_faces(pic1,mtcnn, resnet)
faces_emb, img = load_known_faces(pic2, mtcnn,
resnet)
#待检测⼈物图
isExistDst = match_faces(faces_emb, known_faces_emb, MatchThreshold)
#⼈脸匹配
if isExistDst:
boxes, prob, landmarks = mtcnn.detect(img, landmarks=True)
#返回⼈脸框,概率,5个⼈脸关键点
result='匹配,是同一个人'
else:
result='不匹配,不是同一个人'
d_path=detect(pic1)
b_path=dlib(pic2)
return render_template("index.html",result=result,pic1=pic1,pic2=pic2,d_path=d_path,b_path=b_path)
def detect(filename):
face_cascade = cv2.CascadeClassifier(
'/Users/yangqianyi/Documents/Anaconda3/anaconda3/lib/python3.9/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.imshow('Person Detected!', img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()
detect_path = "static/detect.jpg"
cv2.imwrite(detect_path, img)
return detect_path
def dlib(filename):
import cv2
import dlib
# 读取图⽚
img = cv2.imread(filename)
# 灰度化处理
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 获得脸部位置检测器
detector = dlib.get_frontal_face_detector()
# 初步⼈脸检测,框出矩形。返回值是<class 'dlib.dlib.rectangle'>,即⼀个矩形,表示 为能够唯⼀表示这个⼈脸矩形框两个点坐标:左上⻆(x1,y1)、右下⻆(x2,y2
dets = detector(gray, 1)
# 使⽤模型构建特征提取器,返回5/68个特征点的位置 #此处路径是⾃⼰的python路径下site-packages位置
predictor = dlib.shape_predictor(
r"/Users/yangqianyi/Documents/Anaconda3/anaconda3/lib/python3.9/site-packages/shape_predictor_68_face_landmarks.dat")
for face in dets:
shape = predictor(img, face)
for pt in shape.parts():
pt_pos = (pt.x, pt.y)
cv2.circle(img, pt_pos, 2, (0, 255, 0), 1)
# cv2.imshow("image", img)
dlib_path = "static/dlib.jpg"
cv2.imwrite(dlib_path, img)
return dlib_path
if __name__ == '__main__':
app.run(debug=True)