当前位置:首页 > 厂商动态 > 米尔电子
[导读]Facenet-PyTorch 是一个基于 PyTorch 框架实现的人脸识别库。它提供了 FaceNet 模型的 PyTorch 实现,可以用于训练自己的人脸识别模型。FaceNet 是由 Google 研究人员提出的一种深度学习模型,专门用于人脸识别任务。

本文将介绍基于米尔电子MYD-LT527开发板(米尔基于全志 T527开发板)的FacenetPytorch人脸识别方案测试。

一、深度神经网络

1.简介

Facenet-PyTorch 是一个基于 PyTorch 框架实现的人脸识别库。它提供了 FaceNet 模型的 PyTorch 实现,可以用于训练自己的人脸识别模型。FaceNet 是由 Google 研究人员提出的一种深度学习模型,专门用于人脸识别任务。

在利用PyTorch神经网络算法进行人脸图像对比的实验设置中,我们专注于对比环节,而不涉及实际项目的完整实现细节。但为了贴近实际应用,我们可以构想以下流程:

1)捕捉新人脸图像:首先,我们使用摄像头或其他图像采集设备捕捉一张新的人脸照片。

2)加载存储的人脸图像:接着,从数据库中加载所有已存储的人脸图像。这些图像是之前采集并存储的,用于与新捕捉到的人脸照片进行对比。

3)构建神经网络模型:为了实现对比功能,我们需要一个预先训练好或自定义的神经网络模型。这个模型能够提取人脸图像中的关键特征,使得相似的图像在特征空间中具有相近的表示。

4)特征提取:利用神经网络模型,对新捕捉到的人脸照片和存储的每一张人脸图像进行特征提取。这些特征向量将用于后续的对比计算。

5)计算相似度:采用合适的相似度度量方法(如余弦相似度、欧氏距离等),计算新照片特征向量与存储图像特征向量之间的相似度。

6)确定匹配图像:根据相似度计算结果,找到与新照片相似度最高的存储图像,即认为这两张图像匹配成功。

7)输出匹配结果:最后,输出匹配成功的图像信息或相关标识,以完成人脸对比的实验任务。

2.核心组件

MTCNN:Multi-task Cascaded Convolutional Networks,即多任务级联卷积网络,专门设计用于同时进行人脸检测和对齐。它在处理速度和准确性上都有出色的表现,是当前人脸检测领域的主流算法之一。

FaceNet:由Google研究人员提出的一种深度学习模型,专门用于人脸识别任务。FaceNet通过将人脸图像映射到一个高维空间,使得同一个人的不同图像在这个空间中的距离尽可能小,而不同人的图像距离尽可能大。这种嵌入表示可以直接用于人脸验证、识别和聚类。

米尔基于全志T527开发板

3.功能

支持人脸检测:使用MTCNN算法进行人脸检测,能够准确识别出图像中的人脸位置。

支持人脸识别:使用FaceNet算法进行人脸识别,能够提取人脸特征并进行相似度计算,实现人脸验证和识别功能。

二、安装facenet_pytorch库

1.更新系统

更新ubuntu系统,详情查看米尔提供的资料文件

2.更新系统软件

apt-get update

3.安装git等支持软件

sudo apt-get install -y python3-dev python3-pip libopenblas-dev libssl-dev libffi-dev git cmake

4.安装Pytorch支持工具

# 克隆 PyTorch 源代码

git clone --recursive https://github.com/pytorch/pytorch

# 进入 PyTorch 目录

cd pytorch

# 安装 PyTorch (需要根据你的需求选择 CUDA 版本,如果不需要 GPU 支持则不需要 --cuda 参数)

pip3 install --no-cache-dir torch -f https://download.pytorch.org/whl/torch_stable.html

# 测试 PyTorch 安装

python3 -c "import torch; print(torch.__version__)"

5.安装facenet_pytorch

pip3 install facenet_pytorch

三、CSDN参考案例

1.代码实现

############face_demo.py#############################

import cv2

import torch

from facenet_pytorch import MTCNN, InceptionResnetV1


# 获得人脸特征向量

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模型获取人脸对应的特征向量

  print("\n人脸对应的特征向量为:\n", known_faces_emb)

  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()

  print("\n两张人脸的欧式距离为:%.2f" % distance)

  if (distance < threshold):

    isExistDst = True

  return isExistDst


if __name__ == '__main__':

  # help(MTCNN)

  # help(InceptionResnetV1)

  # 获取设备

  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 # 人脸特征向量匹配阈值设置


  known_faces_emb, _ = load_known_faces('yz.jpg', mtcnn, resnet) # 已知人物图

  faces_emb, img = load_known_faces('yz1.jpg', mtcnn, resnet) # 待检测人物图

  isExistDst = match_faces(faces_emb, known_faces_emb, MatchThreshold) # 人脸匹配

  print("设置的人脸特征向量匹配阈值为:", MatchThreshold)

  if isExistDst:

     boxes, prob, landmarks = mtcnn.detect(img, landmarks=True)

     print('由于欧氏距离小于匹配阈值,故匹配')

else:

    print('由于欧氏距离大于匹配阈值,故不匹配')

此代码是使用训练后的模型程序进行使用,在程序中需要标明人脸识别对比的图像。

2.实践过程

第一次运行时系统需要下载预训练的vggface模型,下载过程较长,后面就不需要在下载了运行会很快。如图所示:

3.程序运行异常呗终止

运行程序,提示killed,系统杀死了本程序的运行,经过多方面的测试,最终发现是识别的图片过大,使得程序对内存消耗过大导致。后将图片缩小可以正常运行了。

以下是对比图像和对比结果。

gitHub开源代码

首先下载代码文件

代码库中,大致的介绍了facenet算法的训练步骤等。

代码实现

以下是facenet的python代码,注意需要更改下面的一条程序"cuda" False,因为t527使用的是cpu,芯片到时自带gpu但是cuda用不了,因为cuda是英伟达退出的一种计算机架构。

import matplotlib.pyplot as plt

import numpy as np

import torch

import torch.backends.cudnn as cudnn

from nets.facenet import Facenet as facenet

from utils.utils import preprocess_input, resize_image, show_config

#--------------------------------------------#

# 使用自己训练好的模型预测需要修改2个参数

# model_path和backbone需要修改!

#--------------------------------------------#

class Facenet(object):

_defaults = {

#--------------------------------------------------------------------------#

# 使用自己训练好的模型进行预测要修改model_path,指向logs文件夹下的权值文件

# 训练好后logs文件夹下存在多个权值文件,选择验证集损失较低的即可。

# 验证集损失较低不代表准确度较高,仅代表该权值在验证集上泛化性能较好。

#--------------------------------------------------------------------------#

"model_path" : "model_data/facenet_mobilenet.pth",

#--------------------------------------------------------------------------#

# 输入图片的大小。

#--------------------------------------------------------------------------#

"input_shape" : [160, 160, 3],

#--------------------------------------------------------------------------#

# 所使用到的主干特征提取网络

#--------------------------------------------------------------------------#

"backbone" : "mobilenet",

#-------------------------------------------#

# 是否进行不失真的resize

#-------------------------------------------#

"letterbox_image" : True,

#-------------------------------------------#

# 是否使用Cuda

# 没有GPU可以设置成False

#-------------------------------------------#

"cuda" : False,

}

@classmethod

def get_defaults(cls, n):

if n in cls._defaults:

return cls._defaults[n]

else:

return "Unrecognized attribute name '" + n + "'"

#---------------------------------------------------#

# 初始化Facenet

#---------------------------------------------------#

def __init__(self, **kwargs):

self.__dict__.update(self._defaults)

for name, value in kwargs.items():

setattr(self, name, value)

self.generate()

show_config(**self._defaults)

def generate(self):

#---------------------------------------------------#

# 载入模型与权值

#---------------------------------------------------#

print('Loading weights into state dict...')

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

self.net = facenet(backbone=self.backbone, mode="predict").eval()

self.net.load_state_dict(torch.load(self.model_path, map_location=device), strict=False)

print('{} model loaded.'.format(self.model_path))

if self.cuda:

self.net = torch.nn.DataParallel(self.net)

cudnn.benchmark = True

self.net = self.net.cuda()

#---------------------------------------------------#

# 检测图片

#---------------------------------------------------#

def detect_image(self, image_1, image_2):

#---------------------------------------------------#

# 图片预处理,归一化

#---------------------------------------------------#

with torch.no_grad():

image_1 = resize_image(image_1, [self.input_shape[1], self.input_shape[0]], letterbox_image=self.letterbox_image)

image_2 = resize_image(image_2, [self.input_shape[1], self.input_shape[0]], letterbox_image=self.letterbox_image)

photo_1 = torch.from_numpy(np.expand_dims(np.transpose(preprocess_input(np.array(image_1, np.float32)), (2, 0, 1)), 0))

photo_2 = torch.from_numpy(np.expand_dims(np.transpose(preprocess_input(np.array(image_2, np.float32)), (2, 0, 1)), 0))

if self.cuda:

photo_1 = photo_1.cuda()

photo_2 = photo_2.cuda()

#---------------------------------------------------#

# 图片传入网络进行预测

#---------------------------------------------------#

output1 = self.net(photo_1).cpu().numpy()

output2 = self.net(photo_2).cpu().numpy()

#---------------------------------------------------#

# 计算二者之间的距离

#---------------------------------------------------#

l1 = np.linalg.norm(output1 - output2, axis=1)

plt.subplot(1, 2, 1)

plt.imshow(np.array(image_1))

plt.subplot(1, 2, 2)

plt.imshow(np.array(image_2))

plt.text(-12, -12, 'Distance:%.3f' % l1, ha='center', va= 'bottom',fontsize=11)

plt.show()

return l1

代码实现

此代码调用的签名的代码,但其可以直接的去调用图片进行人脸识别

from PIL import Image

from facenet import Facenet

if __name__ == "__main__":

model = Facenet()

while True:

image_1 = input('Input image_1 filename:')

try:

image_1 = Image.open(image_1)

except:

print('Image_1 Open Error! Try again!')

continue

image_2 = input('Input image_2 filename:')

try:

image_2 = Image.open(image_2)

except:

print('Image_2 Open Error! Try again!')

continue

probability = model.detect_image(image_1,image_2)

print(probability)

程序运行

运行程序后首先显示的是程序的配置信息,然后可以输入图像对比检测的内容。以下是图像识别的效果和对比的准确率。


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭