OpenCV+Flask将人脸检测、识别内容放入网页

是基于之前的博客写的,这次主要是把结果通过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)

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值