1. 程式人生 > >OpenFace學習(1):安裝配置及人臉比對

OpenFace學習(1):安裝配置及人臉比對

前言

前幾天在網上看到了openface(連結),覺得挺有趣就下載配置了一下,稍微修改了一下跑了個demo,效果還是很不錯的。這裡分享下安裝配置的過程以及demo。

簡介

環境搭建

我只是在筆記本上搭建了環境所以涉及到GPU的CUDA驅動的部分沒有安裝,只是裝了CPU版本的,速度也還可以。我的電腦上此前就配好了opencv、dlib等環境,所以實際配置時僅僅是配置了Torch而已。網上也有很多配置環境的教程,所以下面簡要帶過。
1、OpenCV
直接用命令列安裝:

sudo apt-get install libopencv-dev
sudo apt-get install python-opencv
sudo pip install dlib

3、下載openface原始碼

git clone https://github.com/cmusatyalab/openface.git 

另外把依賴的python庫安裝一下:

cd openface
sudo pip install -r requirements.txt

4、安裝Torch

git clone https://github.com/torch/distro.git ~/torch --recursive
cd torch
bash install-deps
./install.sh

中途可能執行./install.sh

時從github下載檔案時會花費較多時間,如果程序中斷後,可以執行./update.sh繼續安裝。
安裝完成後,使剛剛配置的環境變數立刻生效:

source ~/.bashrc

5、安裝依賴的 LUA庫
由於openface中用到了lua語言,所以還需要安裝一些lua庫。
如果torch安裝成功,應該可以在下面的目錄中找到luarocks這個檔案:

/home/xhb/torch/install/bin/

如果沒有就手動安裝luarocks

sudo apt-get install luarocks

兩個都是一樣的,接下來就以前者為例了:
找到torch中的luarocks來安裝一些包:
注:cunn使用了cuda,如果不使用GPU來跑的話,不需要安裝這個;fblualib和torchx都是用來訓練DNN的,建議安裝。

/home/xhb/torch/install/bin/luarocks install dpnn  
/home/xhb/torch/install/bin/luarocks install nn  
/home/xhb/torch/install/bin/luarocks install optim  
/home/xhb/torch/install/bin/luarocks install csvigo  
/home/xhb/torch/install/bin/luarocks install cunn
/home/xhb/torch/install/bin/luarocks install fblualib  
/home/xhb/torch/install/bin/luarocks install torchx  

安裝結束後,用指令th來驗證是否安裝成功。

6、編譯openface原始碼

python setup.py build
sudo python setup.py install

7、驗證幾個模組是否安裝成功
python中輸入:

import cv2
import dlib
import openface

如果沒有報錯,即安裝成功。

8、下載預訓練模型
在原始碼中提供了下載模型的指令碼,執行即可自動下載幾個模型檔案:

cd openface
./models/get-models.sh

隨後再執行./models/get-models.sh,驗證無誤即可:
png

demo

程式碼

log.py

這段程式碼是用來配置終端列印輸出資訊的,供另外一個py程式碼呼叫。

# *_*coding:utf-8 *_*
# author: 許鴻斌
# 郵箱:[email protected]

import logging
import sys

# 獲取logger例項,如果引數為空則返回root logger
logger = logging.getLogger('Test')
# 指定logger輸出格式
formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s')
# 檔案日誌
# file_handler = logging.FileHandler("test.log")
# file_handler.setFormatter(formatter)  # 可以通過setFormatter指定輸出格式
# 控制檯日誌
console_handler = logging.StreamHandler(sys.stdout)
console_handler.formatter = formatter  # 也可以直接給formatter賦值
# 為logger新增的日誌處理器
# logger.addHandler(file_handler)
logger.addHandler(console_handler)
# 指定日誌的最低輸出級別,預設為WARN級別
logger.setLevel(logging.INFO)

face_compare.py

這裡是實際對人臉進行匹配的程式碼。

# *_*coding:utf-8 *_*
# author: 許鴻斌
# 郵箱:2775751197@qq.com

import time
start = time.time()

import cv2
import itertools
import os
import numpy as np
import openface
import argparse
from log import logger

dlib_model_dir = '/home/xhb/文件/Packages/openface/models/dlib'
openface_model_dir = '/home/xhb/文件/Packages/openface/models/openface'

parser = argparse.ArgumentParser()
parser.add_argument('imgs', type=str, nargs='+', help='Input images.')
parser.add_argument('--dlibFacePredictor', type=str, help="Path to dlib's face predictor.", default=os.path.join(dlib_model_dir, "shape_predictor_68_face_landmarks.dat"))
parser.add_argument('--networkModel', type=str, help="Path to Torch network model.", default=os.path.join(openface_model_dir, 'nn4.small2.v1.t7'))
parser.add_argument('--imgDim', type=int, help="Default image dimension.", default=96)
parser.add_argument('--verbose', action='store_true')

args = parser.parse_args()

if args.verbose:
    logger.info("Argument parsing and loading libraries took {} seconds.".format(time.time() - start))

start = time.time()
align = openface.AlignDlib(args.dlibFacePredictor)
net = openface.TorchNeuralNet(args.networkModel, args.imgDim)
if args.verbose:
    logger.info("Loading the dlib and OpenFace models took {} seconds.".format(
        time.time() - start))

def getRep(imgPath):
    if args.verbose:
        logger.info("Processing {}.".format(imgPath))
    bgrImg = cv2.imread(imgPath)
    if bgrImg is None:
            raise Exception("Unable to load image: {}".format(imgPath))
    rgbImg = cv2.cvtColor(bgrImg, cv2.COLOR_BGR2RGB)

    if args.verbose:
            logger.info("Original size: {}".format(rgbImg.shape))   

    start = time.time()
    faceBoundingBox = align.getLargestFaceBoundingBox(rgbImg)
    if faceBoundingBox is None:
        raise Exception("Unable to find a face: {}".format(imgPath))
    if args.verbose:
        logger.info("Face detection took {} seconds.".format(tim.time() - start))

    start = time.time()
    alignedFace = align.align(args.imgDim, rgbImg, faceBoundingBox, landmarkIndices=openface.AlignDlib.OUTER_EYES_AND_NOSE)     
    if alignedFace is None:
        raise Exception("Unable to align image: {}".format(imgPath))
    if args.verbose:
        logger.info("Face alignment took {} seconds.".format(time.time() - start))

    start = time.time()
    rep = net.forward(alignedFace)  
    if args.verbose:
        logger.info("OpenFace forward pass took {} seconds.".format(time.time()-start))
        logger.info("Representation:")
        logger.info(rep)

    return rep

for (img1, img2) in itertools.combinations(args.imgs, 2):
    distance = getRep(img1) - getRep(img2)
    logger.info("Comparing {} with {}.".format(img1, img2))
    logger.info("Squared l2 distance between representations: {:0.3f}".format(np.dot(distance, distance)))

程式碼都比較簡單,不做詳細介紹了。但是,還有幾個地方要注意修改一下:

dlib_model_dir = '/home/xhb/文件/Packages/openface/models/dlib'
openface_model_dir = '/home/xhb/文件/Packages/openface/models/openface'

這裡兩個目錄分別指的是存放我們之前下載模型的存放的目錄,修改成自己電腦中對應的路徑就行。
目錄下應該有如下圖中所示的檔案:
png

執行結果

我在網上隨便蒐集了一些圖片,用來測試:
png
在終端下執行face_compare.py

python face_compare.py ./test_images/*

執行結果截圖如下:
png
同一個人臉的特徵向量之間的歐式距離比較小,一般都小於1;不同人臉的特徵向量之間的歐式距離較大,一般都有1.5左右。

後記

最近都在忙畢業論文,另外還要參加學校的足球比賽,學習之餘還需要經常去拉練體能,沒有多少時間上部落格。下次有時間,再寫幾個openface的demo,或者復現一下facenet,感覺還是挺有趣的。