pytorch-FaceNet(添加face match function)

该博客介绍了一个基于FaceNet的人脸识别系统,用于进行一对一和一对多的人脸匹配。首先定义了Facenet类,加载预训练模型并进行图片预处理,然后在Face_match函数中实现了对未知人脸与人脸库的匹配,返回最相似的人脸。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FaceNet class(见 bubbliiiing-github

class Facenet(object):
    _defaults = {
        #--------------------------------------------------------------------------#
        #   使用自己训练好的模型进行预测要修改model_path,指向logs文件夹下的权值文件
        #   训练好后logs文件夹下存在多个权值文件,选择验证集损失较低的即可。
        #   验证集损失较低不代表准确度较高,仅代表该权值在验证集上泛化性能较好。
        #--------------------------------------------------------------------------#
        "model_path"    : "model_data/facenet_inception_resnetv1.pth",
        #--------------------------------------------------------------------------#
        #   输入图片的大小。
        #--------------------------------------------------------------------------#
        "input_shape"   : [160, 160, 3],
        #--------------------------------------------------------------------------#
        #   所使用到的主干特征提取网络
        #--------------------------------------------------------------------------#
        "backbone"      : "inception_resnetv1",
        #-------------------------------------------#
        #   是否进行不失真的resize
        #-------------------------------------------#
        "letterbox_image"   : True,
        #-------------------------------------------#
        #   是否使用Cuda
        #   没有GPU可以设置成False
        #-------------------------------------------#
        "cuda"              : True,
    }

    @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()
        
    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,mode):
        #---------------------------------------------------#
        #   图片预处理,归一化
        #---------------------------------------------------#
        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)

        if mode == True:
            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

添加 Face match 功能,一对多的匹配。

import os

from PIL import Image

from facenet import Facenet


def Face_match(face_path, face_database, mode):
    """
    :param face_path: 放需要检测的人脸
    :param face_database: 匹配的人脸库
    :param mode: True/False 是否需要展示匹配的图片(同时显示distance)
    :return: 
    """

    model = Facenet ()

    face_unkonw_path = face_path
    face_known_path = face_database

    face_unknown = []
    face_database = []

    for file in os.listdir (face_unkonw_path):
        face_unknown.append (file)
    for file in os.listdir (face_known_path):
        face_database.append (file)

    print ('-' * 60)
    print ("Unknowm faces: {} ".format (face_unknown))
    print ("Face database: {} ".format (face_database))
    print ('-' * 60)

    for unkonw_face in face_unknown:

        face_distance = []
        face_path_1 = os.path.join (face_unkonw_path, unkonw_face)
        face_img_1 = Image.open (face_path_1)

        for face in face_database:
            face_path_2 = os.path.join (face_known_path, face)
            face_img_2 = Image.open (face_path_2)

            probability = model.detect_image (face_img_1, face_img_2, mode)
            face_distance.append (probability[0])

        index = face_distance.index (min (face_distance))
        print ("The matched face for {} is: {} ".format (unkonw_face, face_database[index]))


if __name__ == "__main__":
    face_unkonw_path = r'FaceImages'
    face_known_path = r'FaceDatabase'
    mode = False

    Face_match (face_unkonw_path, face_known_path, mode)

在这里插入图片描述
在这里插入图片描述

### 实现人脸和指纹图像采集、识别与比对的技术方案 #### 一、人脸图像采集、识别与比对方法 人脸图像的采集主要依赖于摄像机或摄像头等设备。这些设备能够捕捉含有面部特征的信息并转换成数字信号供后续处理。 对于人脸识别而言,其核心在于提取面部的关键特征点,并构建相应的模型用于匹配操作。具体过程如下: - **数据预处理**:获取原始图片后,需去除噪声干扰因素并对图像尺寸标准化以便统一输入给算法。 - **特征提取**:利用深度学习框架中的卷积神经网络(Convolutional Neural Network, CNN),可以有效地从大量样本集中训练得到具有区分度高的局部纹理描述子作为个体的身份标识[^1]。 - **相似度计算**:当新的人脸被抓取之后,则会再次经历上述流程获得对应的向量表示形式;随后通过余弦距离或其他衡量标准评估两者之间的差异程度从而判断是否属于同一对象。 ```python import cv2 from facenet_pytorch import MTCNN, InceptionResnetV1 def face_recognition(image_path): mtcnn = MTCNN() resnet = InceptionResnetV1(pretrained='vggface2').eval() img = cv2.imread(image_path) # Detect faces and extract embeddings using pre-trained model boxes, _ = mtcnn.detect(img) aligned_faces = [] for box in boxes: cropped_face = img[int(box[1]):int(box[3]), int(box[0]):int(box[2])] aligned_faces.append(cropped_face) embeddings = resnet(mtcnn(cv2.cvtColor(aligned_faces[-1], cv2.COLOR_BGR2RGB)).unsqueeze(0)) return embeddings.detach().numpy()[0] ``` #### 二、指纹图像采集、识别与比对方法 指纹图像采集一般由专门设计的手指扫描仪完成。这类仪器能精确记录下皮肤表面细微结构的变化情况形成独一无二的纹路图案。 针对指纹识别来说,主要是依靠特定区域内的脊线分布模式来进行编码表征。以下是基本的工作原理概述: - **增强对比度**:由于实际环境中可能存在光照不均等问题影响最终效果,因此有必要先改善画质质量使得细节更加清晰可见。 - **细化轮廓线条**:经过滤波器平滑处理后的灰阶图会被进一步转化为只有黑白两色构成的理想化版本,在此基础上更容易定位出重要的节点位置。 - **建立模板库**:事先录入多份不同用户的印迹资料存入数据库内等待查询调用之时提供参照依据。 - **执行验证逻辑**:每当有新的请求到来时即刻启动检索机制寻找最接近的那个候选项输出结果。 ```matlab function result = fingerprint_match(templateA, templateB) % Load the two templates to be compared. imgA = imread(templateA); imgB = imread(templateB); % Perform preprocessing on both images (enhancement). processedImgA = enhance_fingerprint_image(imgA); processedImgB = enhance_fingerprint_image(imgB); % Extract minutiae points from each image. [minutiaePointsA, orientationFieldA] = get_minutia_points(processedImgA); [minutiaePointsB, orientationFieldB] = get_minutia_points(processedImgB); % Match fingerprints based on extracted features. result = match_based_on_features(minutiaePointsA, minutiaePointsB, ... orientationFieldA, orientationFieldB); end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值