<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          (附代碼)實(shí)戰(zhàn) | PyTorch+OpenCV進(jìn)行人臉識(shí)別

          共 20004字,需瀏覽 41分鐘

           ·

          2021-06-10 19:26

          點(diǎn)擊左上方藍(lán)字關(guān)注我們



          全網(wǎng)搜集目標(biāo)檢測(cè)相關(guān),人工篩選最優(yōu)價(jià)值內(nèi)容

          編者薦語
          人臉識(shí)別是一種用于從圖像或視頻中識(shí)別人臉的系統(tǒng)。它在許多應(yīng)用程序和垂直行業(yè)中應(yīng)用廣泛。如今,我們看到這項(xiàng)技術(shù)可幫助新聞機(jī)構(gòu)在重大事件報(bào)道中識(shí)別名人,為移動(dòng)應(yīng)用程序提供二次身份驗(yàn)證,為媒體和娛樂公司自動(dòng)索引圖像和視頻文件等。


          前言:
          在這個(gè)博客中,我嘗試構(gòu)建一個(gè)人臉識(shí)別系統(tǒng),該系統(tǒng)將一個(gè)人的圖像與數(shù)據(jù)集中的護(hù)照大小的照片相匹配,并輸出該圖像是否匹配。
          該系統(tǒng)可分為以下部分:人臉檢測(cè)和人臉分類器

          人臉檢測(cè)

          首先,將加載包含護(hù)照尺寸的圖像和自拍照的數(shù)據(jù)集。然后將其分為訓(xùn)練數(shù)據(jù)和驗(yàn)證數(shù)據(jù)。
          pip install split-folders
          該庫有助于將數(shù)據(jù)集劃分為訓(xùn)練,測(cè)試和驗(yàn)證數(shù)據(jù)。
          import splitfolders
          splitfolders.ratio('dataset', output="/data", seed=1337, ratio=(.80.2))
          這將創(chuàng)建一個(gè)包含訓(xùn)練和有效子文件夾的數(shù)據(jù)目錄,將數(shù)據(jù)集分別劃分為80%訓(xùn)練集和20%驗(yàn)證集。
          現(xiàn)在,我們將嘗試從圖像中提取人臉。為此,我將OpenCV的預(yù)訓(xùn)練Haar Cascade分類器用于人臉。
          首先,我們需要加載haarcascade_frontalface_default XML分類器。然后以灰度模式加載我們的輸入圖像(或視頻)。如果找到人臉,則將檢測(cè)到的人臉的位置返回為Rect(x,y,w,h)。然后,將這些位置用于為人臉創(chuàng)建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 faces
                      faces = face_cascade.detectMultiScale(gray, 1.14)
                      # Draw rectangle around the faces
                      for (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)
          這會(huì)將目錄中的所有圖像替換為圖像中檢測(cè)到的人臉。分類器的數(shù)據(jù)準(zhǔn)備部分現(xiàn)已完成。
          現(xiàn)在,我們將加載該數(shù)據(jù)集。
          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
          這將導(dǎo)入所有必需的庫?,F(xiàn)在我們將加載數(shù)據(jù)集,為了增加數(shù)據(jù)集的大小,應(yīng)用了各種數(shù)據(jù)擴(kuò)充。
          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.4850.4560.406], [0.2290.2240.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.4850.4560.406], [0.2290.2240.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
          現(xiàn)在讓我們可視化數(shù)據(jù)集。
          def imshow(inp, title=None):
              """Imshow for Tensor."""
              inp = inp.numpy().transpose((120))
              mean = np.array([0.4850.4560.406])
              std = np.array([0.2290.2240.225])
              inp = std * inp + mean
              inp = np.clip(inp, 01)
              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])
          現(xiàn)在讓我們建立分類器模型。在這里,我們將使用在VGGFace2數(shù)據(jù)集上預(yù)訓(xùn)練的InceptionResnetV1作為基礎(chǔ)模型。
          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 layers

          model_ft = nn.Sequential(*list(model_ft.children())[:-5])

          for param in model_ft.parameters():
              param.requires_grad = False
              
          class Flatten(nn.Module):
              def __init__(self):
                  super(Flatten, self).__init__()
                  
              def forward(self, x):
                  x = x.view(x.size(0), -1)
                  return x
                
          class 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
          現(xiàn)在我們將訓(xùn)練模型。
          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.0
              for epoch in range(num_epochs):
                  print('Epoch {}/{}'.format(epoch, num_epochs - 1))
                  print('-' * 10)
              # Each epoch has a training and validation phase
                  for phase in ['train''val']:
                      if phase == 'train':
                          model.train()  # Set model to training mode
                      else:
                          model.eval()   # Set model to evaluate mode
                      running_loss = 0.0
                      running_corrects = 0
                      # Iterate over data.
                      for inputs, labels in dataloaders[phase]:
                          inputs = inputs.to(device)
                          labels = labels.to(device)
                          # zero the parameter gradients
                          optimizer.zero_grad()
                          # forward
                          # track history if only in train
                          with torch.set_grad_enabled(phase == 'train'):
                              outputs = model(inputs)
                              _, preds = torch.max(outputs, 1)
                              loss = criterion(outputs, labels)
                              # backward + optimize only if in training phase
                              if phase == 'train':
                                  loss.backward()
                                  optimizer.step()
                                  scheduler.step()
                          
                          FT_losses.append(loss.item())
                          # statistics
                          running_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 model
                      if phase == 'val' and epoch_acc > best_acc:
                          best_acc = epoch_acc
                          best_model_wts = copy.deepcopy(model.state_dict())
              time_elapsed = time.time() - since
              print('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 weights
              model.load_state_dict(best_model_wts)
              return model, FT_losses
          最后,我們將評(píng)估模型并保存。
          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")
          現(xiàn)在,我們將輸入圖像輸入已保存的模型并檢查匹配情況。
          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 img
              img = cv2.imread(img_path)
              gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
              # Detect faces
              faces = face_cascade.detectMultiScale(gray, 1.14)
              # Draw rectangle around the faces
              for (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 false
              
              saved_data = torch.load('model.pt'# loading data.pt file
              embedding_list = saved_data[0# getting embedding data
              name_list = saved_data[1# getting list of names
              dist_list = [] # list of matched distances, minimum distance is used to identify the person
              
              for 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



          整理不易,點(diǎn)贊三連↓

          瀏覽 170
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  影音一区二区三区 | 欧美人妇做爰免费视频 | 超碰人人操97 | 深夜福利小视频 | 黄色美女操逼 |