人脸识别是一种用于从图像或视频中识别人脸的系统。它在许多应用程序和垂直行业中很有用。如今,我们看到这项技术可帮助新闻机构在重大事件报道中识别名人,为移动应用程序提供二次身份验证,为媒体和娱乐公司自动索引图像和视频文件,允许人道主义团体识别和营救人口贩卖受害者。

在这个博客中,我尝试构建一个人脸识别系统,该系统将一个人的图像与数据集中的护照大小的照片相匹配,并输出该图像是否匹配。

该系统可分为以下部分:人脸检测和人脸分类器

人脸检测

首先,将加载包含护照尺寸的图像和自拍照的数据集。然后将其分为训练数据和验证数据。

pip install split-folders

该库有助于将数据集划分为训练,测试和验证数据。

import splitfolders
splitfolders.ratio('dataset', output="/data", seed=1337, ratio=(.8, 0.2))

这将创建一个包含训练和有效子文件夹的数据目录,将数据集分别划分为80%训练集和20%验证集。

现在,我们将尝试从图像中提取人脸。为此,我将OpenCV的预训练Haar Cascade分类器用于人脸。

首先,我们需要加载haarcascade_frontalface_default XML分类器。然后以灰度模式加载我们的输入图像(或视频)。如果找到人脸,则将检测到的人脸的位置返回为Rect(x,y,w,h)。然后,将这些位置用于为人脸创建ROI。

import fnmatch
import os
from matplotlib import pyplot as plt
import cv2# Load the cascade
face_cascade = cv2.CascadeClassifier('/haarcascade_frontalface_default.xml')paths="/data/"for root,_,files in os.walk(paths):for filename in files: file = os.path.join(root,filename)if fnmatch.fnmatch(file,'*.jpg'):img = cv2.imread(file)        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Detect facesfaces = face_cascade.detectMultiScale(gray, 1.1, 4)# Draw rectangle around the facesfor (x, y, w, h) in faces:crop_face = img[y:y+h, x:x+w]path = os.path.join(root,filename)cv2.imwrite(path,crop_face)

这会将目录中的所有图像替换为图像中检测到的人脸。分类器的数据准备部分现已完成。

现在,我们将加载该数据集。

from torch import nn, optim, as_tensor
from torch.utils.data import Dataset, DataLoader
import torch.nn.functional as F
from torch.optim import lr_scheduler
from torch.nn.init import *
from torchvision import transforms, utils, datasets, models
import cv2
from PIL import Image
from pdb import set_trace
import time
import copy
from pathlib import Path
import os
import sys
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from skimage import io, transform
from tqdm import trange, tqdm
import csv
import glob
import dlib
import pandas as pd
import numpy as np

这将导入所有必需的库。现在我们将加载数据集,为了增加数据集的大小,应用了各种数据扩充。

data_transforms = {'train': transforms.Compose([transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Scale((224,224)),transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4, hue=0.4),transforms.RandomRotation(5, resample=False,expand=False, center=None),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]),'val': transforms.Compose([transforms.ToTensor(),transforms.Scale((224,224)),transforms.ColorJitter(brightness=0.4, contrast=0.4, saturation=0.4, hue=0.4),transforms.RandomRotation(5, resample=False,expand=False, center=None),transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),]),
}
data_dir = '/content/drive/MyDrive/AttendanceCapturingSystem/data/'
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),data_transforms[x])for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x],batch_size=8, shuffle=True)for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train','val']}
class_names = image_datasets['train'].classes
class_names

现在让我们可视化数据集。

def imshow(inp, title=None):"""Imshow for Tensor."""inp = inp.numpy().transpose((1, 2, 0))mean = np.array([0.485, 0.456, 0.406])std = np.array([0.229, 0.224, 0.225])inp = std * inp + meaninp = np.clip(inp, 0, 1)plt.imshow(inp)if title is not None:plt.title(title)plt.pause(0.001)  # pause a bit so that plots are updated
# Get a batch of training data
inputs, classes = next(iter(dataloaders['train']))
# Make a grid from batch
out = utils.make_grid(inputs)
imshow(out, title=[class_names[x] for x in classes])

现在让我们建立分类器模型。在这里,我们将使用在VGGFace2数据集上预训练的InceptionResnetV1作为基础模型。

from models.inception_resnet_v1 import InceptionResnetV1
print('Running on device: {}'.format(device))model_ft = InceptionResnetV1(pretrained='vggface2', classify=False, num_classes = len(class_names))list(model_ft.children())[-6:]layer_list = list(model_ft.children())[-5:] # all final layersmodel_ft = nn.Sequential(*list(model_ft.children())[:-5])for param in model_ft.parameters():param.requires_grad = Falseclass Flatten(nn.Module):def __init__(self):super(Flatten, self).__init__()def forward(self, x):x = x.view(x.size(0), -1)return xclass normalize(nn.Module):def __init__(self):super(normalize, self).__init__()def forward(self, x):x = F.normalize(x, p=2, dim=1)return x
model_ft.avgpool_1a = nn.AdaptiveAvgPool2d(output_size=1)model_ft.last_linear = nn.Sequential(Flatten(),nn.Linear(in_features=1792, out_features=512, bias=False),normalize()
)model_ft.logits = nn.Linear(layer_list[2].out_features, len(class_names))
model_ft.softmax = nn.Softmax(dim=1)
model_ft = model_ft.to(device)
criterion = nn.CrossEntropyLoss()# Observe that all parameters are being optimized
optimizer_ft = optim.SGD(model_ft.parameters(), lr=1e-2, momentum=0.9)# Decay LR by a factor of *gamma* every *step_size* epochs
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)  model_ft = model_ft.to(device)
criterion = nn.CrossEntropyLoss()
# Observe that all parameters are being optimized
optimizer_ft = optim.SGD(model_ft.parameters(), lr=1e-2, momentum=0.9)
# Decay LR by a factor of *gamma* every *step_size* epochs
exp_lr_scheduler = lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)model_ft

现在我们将训练模型。

def train_model(model, criterion, optimizer, scheduler,num_epochs=25):since = time.time()FT_losses = []best_model_wts = copy.deepcopy(model.state_dict())best_acc = 0.0for epoch in range(num_epochs):print('Epoch {}/{}'.format(epoch, num_epochs - 1))print('-' * 10)# Each epoch has a training and validation phasefor phase in ['train', 'val']:if phase == 'train':model.train()  # Set model to training modeelse:model.eval()   # Set model to evaluate moderunning_loss = 0.0running_corrects = 0# Iterate over data.for inputs, labels in dataloaders[phase]:inputs = inputs.to(device)labels = labels.to(device)# zero the parameter gradientsoptimizer.zero_grad()# forward# track history if only in trainwith torch.set_grad_enabled(phase == 'train'):outputs = model(inputs)_, preds = torch.max(outputs, 1)loss = criterion(outputs, labels)# backward + optimize only if in training phaseif phase == 'train':loss.backward()optimizer.step()scheduler.step()FT_losses.append(loss.item())# statisticsrunning_loss += loss.item() * inputs.size(0)running_corrects += torch.sum(preds == labels.data)epoch_loss = running_loss / dataset_sizes[phase]epoch_acc = running_corrects.double() / dataset_sizes[phase]print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))# deep copy the modelif phase == 'val' and epoch_acc > best_acc:best_acc = epoch_accbest_model_wts = copy.deepcopy(model.state_dict())time_elapsed = time.time() - sinceprint('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))print('Best val Acc: {:4f}'.format(best_acc))# load best model weightsmodel.load_state_dict(best_model_wts)return model, FT_losses

最后,我们将评估模型并保存。

model_ft, FT_losses = train_model(model_ft, criterion, optimizer_ft, exp_lr_scheduler, num_epochs=200)
plt.figure(figsize=(10,5))
plt.title("FRT Loss During Training")
plt.plot(FT_losses, label="FT loss")
plt.xlabel("iterations")
plt.ylabel("Loss")
plt.legend()
plt.show()torch.save(model, "/model.pt")

现在,我们将输入图像输入已保存的模型并检查匹配情况。

import fnmatch
import os
from matplotlib import pyplot as plt
import cv2
from facenet_pytorch import MTCNN, InceptionResnetV1
resnet = InceptionResnetV1(pretrained='vggface2').eval()
# Load the cascade
face_cascade = cv2.CascadeClassifier('/haarcascade_frontalface_default.xml')def face_match(img_path, data_path): # img_path= location of photo, data_path= location of data.pt # getting embedding matrix of the given imgimg = cv2.imread(img_path)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Detect facesfaces = face_cascade.detectMultiScale(gray, 1.1, 4)# Draw rectangle around the facesfor (x, y, w, h) in faces:crop_face = img[y:y+h, x:x+w]img = cv2.imwrite(img_path,crop_face)emb = resnet(img.unsqueeze(0)).detach() # detech is to make required gradient falsesaved_data = torch.load('model.pt') # loading data.pt fileembedding_list = saved_data[0] # getting embedding dataname_list = saved_data[1] # getting list of namesdist_list = [] # list of matched distances, minimum distance is used to identify the personfor idx, emb_db in enumerate(embedding_list):dist = torch.dist(emb, emb_db).item()dist_list.append(dist)idx_min = dist_list.index(min(dist_list))return (name_list[idx_min], min(dist_list))result = face_match('trainset/0006/0006_0000546/0006_0000546_script.jpg', '/model.pt')print('Face matched with: ',result[0], 'With distance: ',result[1])

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 mthler」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

使用PyTorch+OpenCV进行人脸识别(附代码演练)相关推荐

  1. 树莓派交叉编译opencv3.4.1/pycharm安装opencv/实现人脸识别Demo记录

    目录 文章目录 目录 前言 树莓派交叉编译opencv3.4.1 安装环境 开始交叉编译 错误记录 WIN10+Anaconda+PyCharm安装opencv3.4.7 WIN10下opencv人脸 ...

  2. 【opencv】基于opencv实现人脸识别,原理代码部分

    上一部分我们解决了环境问题,这一部分我们可以开始上代码,环境没有配好的可以参照上一篇博客:环境搭建解决: 下面先说一下原理: 一.原理部分   本文基于opencv来实现人脸识别,大致实现流程可以描述 ...

  3. 怎样使用OpenCV进行人脸识别

    不断维护的地址:http://plzcoding.com/face-recognition-with-opencv/ 怎样使用OpenCV进行人脸识别 本文大部分来自OpenCV官网上的Face Re ...

  4. Java使用OpenCV实现人脸识别

    通过OpenCV实现人脸识别,包括图片,视频,摄像头中人脸识别. 首先看一下效果(在网上随便找的一张图片): 下面开始说一下如何实现的: 第一步:  需要安装OpenCV 下载链接:https://o ...

  5. PyTorch 模型训练实用教程(附代码)

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx PyTorch 能在短时间内被众多研究人员和工程师接受并推崇是因为其有着诸多优点,如采用 Py ...

  6. java调起本地摄像头,利用openCV进行人脸识别(一)

    嗨咯,又好久没有更新了.今天写个前阵子做的人脸识别程序.该程序客户端基于Jave JFrame 客户端的主要作用是,调用电脑的摄像头(我的直接调用笔记本摄像头),然后回显摄像头录取的信息,再利用ope ...

  7. python视频图片识别算法_python利用Opencv进行人脸识别(视频流+图片)

    首先:需要在在自己本地安装opencv具体步骤可以问度娘 如果从事于开发中的话建议用第三方的人脸识别(推荐阿里) 1.视频流中进行人脸识别 # -*- coding: utf-8 -*- import ...

  8. 基于PCA 人脸识别/人脸识别算法/人脸检测程序源码MATLAB ELM+PCA人脸识别 PCA人脸识别matlab代码 基于PCA算法的人脸识别

    1.基于PCA的人脸识别代码 2.MATLAB ELM+PCA人脸识别 2.基于PCA的人脸识别(matlab)(采用PCA算法进行人脸识别,通过抽取人脸的主要成 分,构成特征脸空间,识别时将测试图像 ...

  9. opencv + face_recognition —— 人脸识别案例

    文章目录 opencv + face_recognition -- 人脸识别案例 0. 版本信息 1. 导包 2. 识别图片中的面部 3. 实现摄像头中的面部追踪 4. 人脸追踪+识别,分析出不同的人 ...

最新文章

  1. 自从上了 SkyWalking,睡觉真香!!
  2. [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)...
  3. 《JavaScript 闯关记》之原型及原型链
  4. [转]一篇很喜欢的知乎美文
  5. 跑不出来_内蒙古23只狍子罕见列队出没,它们是出来透透气?
  6. 初学linux,在Linux上创建c程序并运行!
  7. Linux对运行服务操作命令
  8. 农业部部署农业大数据发展工作 评:对农业现代化很重要
  9. UVALive 7274 Canvas Painting (优先队列)
  10. Linux运维之ntpdate同步网络时间
  11. Selenium模拟浏览器常见操作及问题
  12. Laravel+DingoAPI+Passport使用邮箱或手机号或uid登录
  13. 【java】 drool规则引擎背后的Rete算法
  14. wince车机刷carplay_WINCE 使用 CarPlay,老唐开新花
  15. 安装教程之postman下载及安装
  16. 浙江新华书店的数字化新尝试
  17. 烂土豆搭配令牌窃取提权dll劫持搭配令牌窃取提权不带引号服务路径问题提权不安全的服务权限配置提权
  18. 计算机和网络之间有个感叹号,网络有个感叹号!电脑无线网络连接不上的几种常见问题...
  19. android学习笔记之GoogleMap 【转】
  20. 2022/1/12(自闭半日游)

热门文章

  1. python字符串定义变量名_python 将字符串作为变量名
  2. CodeGear RAD 2007 up4最新下载及破解
  3. XP系统装PhotoShop的CS3版本
  4. Android 分屏模式 问题总结
  5. 2021 全球人工智能技术创新大赛 医学影像报告异常检测 TOP4方案
  6. 【笔记】python的遍历字典:遍历所有键值对(方法items())、遍历字典中的所有键(方法keys())、按特定顺序遍历字典中的所有键、遍历字典中的所有值(方法values())、函数set()
  7. webservice 天气预报的接口
  8. 2006年重大病毒木马事件大阅兵
  9. nyoj995硬币找零完全背包
  10. 支付宝与微信转战刷脸支付,多年相爱相杀情归何处?