快速上手项目1:基于FaceNet的人脸识别项目

news2024/11/24 19:52:56

快速上手项目1:基于FaceNet的人脸识别项目

说明

​ 本来想自己复现一下facenet的,但是发现facenet已经被做成了python的第三方库,于是自己用了用,发现挺简单的,然后又看了看源码,感觉模型架构实现部分很简单,所以就算了。

​ 想了想,决定新开一个系列,就是快速上手项目,主要目的就是尽可能的简单使用一个项目。

GitHub项目地址

​ 想要自己研读代码的,可以把源码下载到本地:

https://github.com/timesler/facenet-pytorch/

目录结构

文章目录

    • 快速上手项目1:基于FaceNet的人脸识别项目
      • 1. 前言
      • 2. 安装
      • 3. 下载预训练权重
      • 4. 方法说明
      • 5. 人脸检测
      • 6. 人脸识别
      • 7. 总结

1. 前言

​ 经常会刷到如何学习人工智能的视频,总会有人说学习CV先跑一个项目,而这个项目大部分都人脸识别。

​ 我也是最近看了人脸识别相关的论文,才知道原来facenet已经把代码做成了一个python第三方库。难怪大家都说要实现人脸识别,因为它真的简单,并且可以在不需要你训练的情况下,直接拿过来用。

2. 安装

  • 方式一:安装包
pip install facenet-pytorch
  • 方法二:下载源码

​ 如果你只想要简单了解这个项目,直接安装facenet-pytorch即可,不过,我们这里还是把源码从GitHub上下过来:

https://github.com/timesler/facenet-pytorch/

​ 因为,想要深入了解,最好还是从源码入手,另外源码还提供了几张测试图片可以用。

​ 这里简单对下载后的GitHub项目进行简单的目录结构说明:

在这里插入图片描述

3. 下载预训练权重

​ 虽然你可以直接使用方法:

from facenet_pytorch import InceptionResnetV1

resnet = InceptionResnetV1(pretrained='vggface2')

​ 来自动下载预训练权重,不过这个下载地址其实是在GitHub上,所以注定了下载比较慢。因此我建议你可以自己下载:

  • 方法一:打开下面链接直接下载
https://github.com/timesler/facenet-pytorch/releases/download/v2.2.9/20180402-114759-vggface2.pt
  • 方法二:用百度网盘下载
链接:https://pan.baidu.com/s/1TPaz_RO4faazUUg6ljftVA 
提取码:dqqi 

​ 下载后,需要把下载的文件放入下面的路径中:

C:\Users\用户\.cache\torch\checkpoints

4. 方法说明

​ 下面对常用的方法进行一定的说明:

  • MTCNN类:创建MTCNN模型,用于人脸的检测

​ 该类的常用初始化参数:

参数意义
image_size输出图像大小,默认160
margin添加到预测框的margin值,默认为0
min_face_size最小的搜索人脸的大小,默认为20
thresholds人脸检测阈值,默认为[0.6, 0.7, 0.7]
factor用于创建图像金字塔的缩放因子,默认为0.709
post_process是否进行后处理,默认为True
select_largest如果为True,返回检测到人脸中最大的,否则返回概率最大的,默认为True
selection_method用何种方式选择人脸,和上面的参数有点类似,默认为None
keep_all如果为True,所有检测到的人脸都返回,默认为False
device指定设备信息,默认为None

​ 该类的常用方法:

方法参数作用举例
前向传播方法图像、保存路径、是否返回概率值基本的运行流程,但是返回人脸的数组mtcnn(img.path.True)
detect图像、是否返回人脸关键点与前向传播类似,但是返回预测框坐标和概率值mtcnn.detect(img,False)
  • InceptionResnetV1类,目的是获取人脸的嵌入向量,用于衡量不同人脸之间的相似性,用于人脸识别
# 常见的用法
# 1. 创建对象
resnet = InceptionResnetV1(pretrained='vggface2').eval().to('cuda')
'''
pretrained,即是否启用预训练模型
'''
# 2. 识别人脸
face_embedding = resnet(img)

5. 人脸检测

​ 其实,如果你下载了GitHub上的源码,你也许已经发现了,作者自己提供了测试代码和如何使用这些代码。(下面的代码参考作者提供的测试代码,我只是稍微修改了一些)

​ 这里,我根据作者的提示简单粗暴的来实现一下人脸检测:

# 导入包
from facenet_pytorch import MTCNN
import cv2
import torch

# 指定设备
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
# 创建对象:这个是作者提供的方法
mtcnn = MTCNN(
    image_size=160, margin=0, min_face_size=20,
    thresholds=[0.6, 0.7, 0.7], factor=0.709, post_process=True,
    device=device
)
# 人脸检测
# 给定一张图片路径
img_path = '../data/test.jpg'
image = cv2.imread(img_path)
# 为了防止图片太大,把它缩放一下,如果图片不大,可以把它注释掉
# image = cv2.resize(image,(500,500))
# 预测
box,prob = mtcnn.detect(image)
# 把结果可视化
cv2.namedWindow('draw')
cv2.rectangle(image,(int(box[0][0]),int(box[0][1])),(int(box[0][2]),int(box[0][3])),(0,0,255))
cv2.imshow('draw',image)
cv2.waitKey(0)

​ 看看预测结果:

在这里插入图片描述

6. 人脸识别

​ 同样的,作者也提供了人脸识别的脚本,注意:人脸检测只需要检测到人脸即可,人脸识别不仅需要检测人脸,还需要识别这个人是谁

​ 那么可以简单的实现一下:

from facenet_pytorch import MTCNN,InceptionResnetV1
import torch
from torch.utils.data import DataLoader
from torchvision import datasets
import numpy as np
import pandas as pd
import os
from PIL import Image, ImageDraw, ImageFont

# 定义加载图像的线程数
workers = 0 if os.name=="nt" else 4
# 定义设备
device = torch.device('cuda:0' if torch.cuda.is_available() else "cpu")
# 创建mtcnn
mtcnn = MTCNN(image_size=160,margin=0,min_face_size=20,thresholds=[0.6,0.7,0.7],
              factor=0.709,post_process=True,device=device
              )
# 创建resnet
resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)
# 定义数据加载器的函数
def collate_fn(x):
    return x[0]
#将所有的单人照图片放在各自的文件夹中,文件夹名字就是人的名字,存放格式如下::
dataset = datasets.ImageFolder("../data/test_images") #加载数据库
dataset.idx_to_class = {i:c for c,i in dataset.class_to_idx.items()}
loader = DataLoader(dataset,collate_fn=collate_fn,num_workers=workers)
aligned = [] #aligned就是从图像上抠出的人脸,大小是之前定义的image_size=160
names = []

# 将获取的人脸图片保存下来,注意路径
i = 1
for x, y in loader:
    path = '../data/test_images_aligned/{}/'.format(dataset.idx_to_class[y])  # 这个是要保存的人脸路径
    # 如果要保存识别到的人脸,在save_path参数指明保存路径即可,不保存可以用None
    x_aligned, prob = mtcnn(x, return_prob=True,save_path= path+ '/{}.jpg'.format(i))
    i = i+1
    # 如果有预测的值,放入结果列表中
    if x_aligned is not None:
        print('Face detected with probability: {:8f}'.format(prob))
        aligned.append(x_aligned)
        names.append(dataset.idx_to_class[y])

# 把获取的值保存下来
aligned = torch.stack(aligned).to(device)
embeddings = resnet(aligned).detach().cpu() #提取所有人脸的特征向量,每个向量的长度是512
#两两之间计算混淆矩阵
dists = [[(e1 - e2).norm().item() for e2 in embeddings] for e1 in embeddings]
print(names)
print(pd.DataFrame(dists, columns=names, index=names))
torch.save(embeddings,'database.pt')  # 当然也可以保存在一个文件
torch.save(names,'names.pt')

#对新的照片进行人脸识别
# mtcnn网络负责检测人脸
mtcnn = MTCNN(keep_all=True, device=device)
resnet = InceptionResnetV1(pretrained='vggface2').eval().to('cuda')
# 加载上面学习到的数据
names = torch.load("./names.pt")
embeddings = torch.load("./database.pt").to('cuda')
def detect_frame(img):
    fontStyle = ImageFont.truetype("arial.ttf", 100,encoding="utf-8")
    faces = mtcnn(img)  # 直接infer所有的faces
    #但是这里相当于两次infer,会浪费时间
    boxes, _ = mtcnn.detect(img)  # 检测出人脸框 返回的是位置
    # frame_draw = img.copy()
    draw = ImageDraw.Draw(img)
    print("检测人脸数目:",len(boxes))
    for i,box in enumerate(boxes):
        print(box)
        draw.rectangle(box.tolist(),outline='white',width=5)  # 绘制框
        face_embedding = resnet(faces[i].unsqueeze(0).to('cuda'))
        #print(face_embedding.size(),'大小')
        # 计算距离
        probs = [(face_embedding - embeddings[i]).norm().item() for i in range(embeddings.size()[0])]
        #print(probs)
        # 我们可以认为距离最近的那个就是最有可能的人,但也有可能出问题,数据库中可以存放一个人的多视角多姿态数据,对比的时候可以采用其他方法,如投票机制决定最后的识别人脸
        index = probs.index(min(probs))   # 对应的索引就是判断的人脸
        name = names[index] # 对应的人脸
        draw.text( (int(box[0]),int(box[1])), str(name), fill=(255,0,0),font=fontStyle)
    return img

if __name__ == '__main__':
    from matplotlib import pyplot as plt
    # 人脸检测
    img_path = '../data/test.jpg'
    img = Image.open(img_path)
    frame = detect_frame(img)
    plt.imshow(frame)
    plt.show()

​ 结果如下:
在这里插入图片描述

7. 总结

​ 这个项目主要的特点是简单,容易扩展。

​ 不过,在源码中,项目架构容易实现,但是具体的细节阅读起来仍需一定的基础。如果感兴趣或者想要提高自己阅读代码能力的朋友,可以去看看项目中的model文件夹。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/558802.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

说说 HWND_TOP 和 HWND_TOPMOST 的区别

初看上去,HWND_TOP 和 HWND_TOPMOST 有点类似,但是实际上在调用 DeferWindowPos 或者 SetWindowPos时,它们之间的差别还挺大。 在同级窗口的维护机制中,有一个概念叫做 Z 序 (Z-order) 。出于此讨论的目的,顶级窗口也…

音容笑貌,两臻佳妙,人工智能AI换脸(deepfake)技术复刻《卡萨布兰卡》名场面(Python3.10)

影史经典《卡萨布兰卡》是大家耳熟能详的传世名作,那一首壮怀激烈,激奋昂扬的马赛曲,应当是通片最为激动人心的经典桥段了,本次我们基于faceswap和so-vits库让AI川普复刻美国演员保罗亨雷德高唱《马赛曲》的名场面。 配置人脸替换…

《斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 8 Advertising on the Web

来源:《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 8 Advertising on the Web There are several factors that must be considered in evaluating ads: The position of the ad in a list has great influence on whether or not it is clicked.…

Linkage Mapper 之 Barrier Mapper 功能解析(含实际案例分析)

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Linkage Mapper解密数字世界链接 大草原松鸡"(Greater Sage Grouse)的Lek Kernals(即HCAs),以及连接、连接障碍和恢复机会效果图: 图片

python+Django音乐播放器网站系统0tr3w

音乐网站系统的后台开发目标是以信息管理系统的管理和开发方法,用目前现有的新技术进行系统开发,提供后台管理员高度友好的界面操作以及迅捷的信息处理。而前台的开发目标是以用户的需求作为主导,提供对用户而言非常友好的界面操作环境以及完…

实时频谱-1.1基本概念

RF信号 RF(射频)是Radio Frequency的缩写,表示可以辐射到空间的电磁频率,频率范围从300KHz~30GHz之间。 中频 IF(intermediate frequency),用来在中频衡量AM或FM调谐器抑制外来干扰的能力,数…

基于springboot在线外卖系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SpringBoot 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:…

You Only Look Once: 革命性目标检测算法论文解析

You Only Look Once 全论文完整翻译 You Only Look Once: Unified, Real-Time Object Detection 摘要 我们介绍了一种名为YOLO的新型目标检测方法。在目标检测的先前工作中,人们将分类器重新应用于执行检测任务。相反,我们将目标检测视为一个回归问题&a…

ChatGPT 的议论文究竟写的怎么样?111 位高中教师告诉你答案

夕小瑶科技说 原创 作者 | 小戏、Python 在 OpenAI GPT-4 发布时发布的《GPT-4 Technical Report》中,其中很吸引人眼球的一部分是 GPT-4 应用于教育领域的出色表现,通过让 GPT-4 去完成美国的 AP 课程及考试,来评估 GPT-4 在多个学科中的性…

WIN提权补丁提权,at,sc,psexes提权

win提权分为web和本地提权 web提权就是getshell后,权限是网站权限,要进行提权 本地提权是本地用户进行提权 本地用户的权限大于网站权限,所以本地提权成功概率比web提权概率大 因为我们做渗透测试,一般都是从网站入侵。所以大…

OpenAI最新iOS版ChatGPT下载使用手册:三步快速下载,支持语音输入和历史聊天记录重新对话(免费、比网页端响应快、亲测可用)

目录 前言ChatGPT移动端与网页端相比的优势步骤一:注册美区Apple id账号步骤二:苹果手机切换appstore id步骤三:下载ChatGPT IOS移动版APP畅玩ChatGPT APP体验总结其它资料下载 ! 前言 北京时间5月19日凌晨,OpenAI重…

散点图(Scatter Plot)

目录 1、散点图 2、随机数据分布 1、散点图 散点图是数据集中的每个值都由点表示的图 Matplotlib 模块有一种绘制散点图的方法,它需要两个长度相同的数组,一个数组用于 x 轴的值,另一个数组用于 y 轴的值 x [5,7,8,7,2,17,2,9,4,11,12,9…

2023最新网络安全面试题大全

2023年快过去一半了,不知道小伙伴们有没有找到自己心仪的工作呀【doge】,本文总结了常见的安全岗位面试题,方便各位复习。祝各位事业顺利,财运亨通。在网络安全的道路上越走越远! 所有的资料都整理成了PDF&#xff0c…

Netty实战(七)

EventLoop和线程模型 一、什么是线程模型二、EventLoop 接口2.14 Netty 4 中的 I/O 和事件处理 三、任务调度3.1 JDK 的任务调度 API3.2 使用 EventLoop 调度任务 四、实现细节4.1 线程管理4.2 EventLoop/线程的分配4.2.1 异步传输4.2.2 .阻塞传输 一、什么是线程模…

Java基础学习---3、堆、GC

1、堆 1.1 概述 1.1.1 堆空间结构 1.1.2 堆空间工作机制 新创建的对象会放在Eden区当Eden区中已使用的空间达到一定比例,会触发Minor GC每一次在Minor GC中没有被清理掉的对象就成了幸存者。幸存者对象会被转移到幸存者区幸存者区分成from区和to区from区快满的时…

如何提高软件复用度,降低项目开发成本?

1、代码基线管控策略 理想的代码复用是我们建立一条主干代码,持续维护下去。面对客户的新需求,需要我们拉一条临时分支来满足客户需求,然后将稳定后的临时分支代码成果回归到主干。这样我们所有的研发成果都可以在一个代码分支上进行追溯&…

FreeRTOS学习之路,以STM32F103C8T6为实验MCU(序章——浅谈单片机以及FreeRTOS)

学习之路主要为FreeRTOS操作系统在STM32F103(STM32F103C8T6)上的运用,采用的是标准库编程的方式,使用的IDE为KEIL5。 注意!!!本学习之路可以通过购买STM32最小系统板以及部分配件的方式进行学习…

论文解读 | 透过窥镜: 透明容器内物体的神经三维重建

原创 | 文 BFT机器人 随着虚拟现实和虚拟世界技术的发展,博物馆藏品的数字化是一个越来越受关注的新兴话题。世界上许多著名的博物馆都在为网上展览建立自己的数字馆藏。 在这些藏品中,有一种特殊而重要的藏品昆虫、人体组织、水生生物和其他易碎的标本需…

ZooKeeper(一):基础介绍

文章目录 什么是 ZooKeeper?ZooKeeper 发展历史ZooKeeper 应用场景ZooKeeper 服务的使用ZooKeeper 数据模型data tree 接口znode 分类 总结 什么是 ZooKeeper? ZooKeeper 是一个分布式的,开放源码的分布式应用程序协同服务。ZooKeeper 的设计…

docker-compose安装nacos 2.2.1及配置

目录 官网 创建存储目录 创建数据库 application.properties配置(重要) docker-compose.yml 启动 登录 下面是安装nacos 2.2.1版本的方法,有一些变化 官网 GitHub - alibaba/nacos: an easy-to-use dynamic service discovery, configu…