首頁>技術>

01

人臉識別簡介

簡單來講,人臉識別這個問題,就是給定兩個人臉,然後判定他們是不是同一個人,這是它最原始的定義。它有很多應用場景,比如銀行櫃檯、海關、手機解鎖、酒店入住、網咖認證,會查身份證跟你是不是同一個人。

關於人臉識別的內容,網上資料很多,這裡推薦一篇綜述,詳細介紹了一些人臉識別的背景和目前的相關研究,以及常用的人臉識別模型:

http://www.elecfans.com/d/709424.html

好了,直接進入主題,今天的重點:

insightface論文:https://arxiv.org/abs/1801.07698

insightface github專案:https://github.com/deepinsight/insightface

02

製作資料集

一、環境配置

官方提供的專案是基於mxnet框架的

因此首先需要配置好這些環境,這裡假設已經安裝好cuda等

mxnet的安裝相對來說比較簡單(相對於caffe)

(1)查詢自己cuda的版本

# 輸入nvcc -V# 輸出結果nvcc: NVIDIA (R) Cuda compiler driverCopyright (c) 2005-2017 NVIDIA CorporationBuilt on Fri_Sep__1_21:08:03_CDT_2017Cuda compilation tools, release 9.0, V9.0.176

(2)用pip安裝mxnet(GPU版本)

pip install mxnet-cu90# 根據自身情況查詢對應的安裝命令,例如我伺服器的cuda版本是10.0的,安裝命令為 pip install mxnet-cu100

二、克隆專案和資料集下載

將insight專案克隆到本地

git clone --recursive https://github.com/deepinsight/insightface.git

下載lfw資料集

連結:http://vis-www.cs.umass.edu/lfw/index.html#download

這裡為了方便,提供了lfw的部分用於練手

練手資料集https://www.lanzous.com/i7gdxva,僅用於製作資料集練手

觀察資料集:

這裡提供了20個用於練手,完整資料集可以去上面的連結或自行查詢下載。

說明:每個資料夾名為人的姓名,資料夾內包含多張人臉(>=1)。

三、開始製作所需要格式的資料集

(1)資料對齊並生成lst檔案

將lfw資料集下載好並放置在datasets下(這裡以lfwdata命名的資料夾),然後新建一個資料夾並命名為output儲存對齊後的人臉圖片,新建一個資料夾命名為train用於儲存輸出結果

執行insightface專案下 src/align下的align_lfw.py檔案

python align_lfw.py --input-dir ../../datasets/lfwdata --output-dir ../../datasets/output

--input :輸入需要對齊的資料的路徑

--output:輸出對齊後的資料儲存路徑

對齊後的圖片

遇到問題1:

ValueError: Object arrays cannot be loaded when allow_pickle=False

解決方案:

pip3 install numpy==1.16.1

如果已安裝了多個numpy版本,需要先將其解除安裝後在執行

遇到問題2:

AttributeError: module 'scipy.misc' has no attribute 'imread'

解決方案:

pip install scipy==1.1.0

如果成功執行,output資料夾下會產生對齊後的人臉以及一個lst檔案(將lst檔案改名為 train.lst,並移動到train檔案下

終端下,移動和重新命名的操作

# 重新命名 mv [原始檔名] [改變後的檔名] mv lst train.lst# 移動 mv [起始檔案路徑] [目標檔案路徑]mv train.lst ../train/

觀察生成的 lst 檔案內容:

1       ../../datasets/train/Abbas_Kiarostami/Abbas_Kiarostami_0001.jpg 01       ../../datasets/train/Abdel_Aziz_Al-Hakim/Abdel_Aziz_Al-Hakim_0001.jpg   1# 其中1代表對齊,最後的數字0,1代表class label 中間是地址;需要用\t表示tab鍵,不能用空格間隔。

(2)建立property配置檔案

在datasets/train下建立property,沒有後綴

寫入下面內容,含義1000,112,112代表ID數量,尺寸,尺寸

1000,112,112

(3)生成rec&idx檔案(依託於lst檔案)

執行src/data face2rec2.py

python face2rec2.py ../../datasets/train/

執行可能會報錯,需要修改,可能原因是原始碼是基於python2的

在python3下執行,修改第105行成如下所示:

s = mx.recordio.pack(header, b'')

執行成功後會出現兩個檔案

train.idx和train.rec

將train.idx, train.rec是放置在train資料夾中,用於後續訓練使用,不然後續建立pair會報錯

(4)建立pair檔案

為了做測試我們需要生成驗證集用的bin檔案,bin檔案生成前需要做pair檔案,就是一對一對的資料,每一行分別是

圖A的目錄 空格 圖B的目錄 空格 標誌0/1(代表兩張圖類別一致否)

在src/data下新建一個程式碼generate_image_pairs.py用於生成pairs

# coding:utf-8import sysimport osimport randomimport timeimport itertoolsimport pdbimport argparse#src = '../../datasets/lfw2'#dst = open('../../datasets/lfw/train.txt', 'a')parser = argparse.ArgumentParser(description='generate image pairs')# generalparser.add_argument('--data-dir', default='', help='')parser.add_argument('--outputtxt', default='', help='path to save.')parser.add_argument('--num-samepairs',default=100)args = parser.parse_args()cnt = 0same_list = []diff_list = []list1 = []list2 = []folders_1 = os.listdir(args.data_dir)dst = open(args.outputtxt, 'a')count = 0dst.writelines('\n')# 產生相同的影象對for folder in folders_1:    sublist = []    same_list = []    imgs = os.listdir(os.path.join(args.data_dir, folder))    for img in imgs:        root_path = os.path.join(args.data_dir, folder, img)        sublist.append(img_root_path)        list1.append(img_root_path)    for item in itertools.combinations(sublist, 2):        for name in item:            same_list.append(name)    if len(same_list) > 10 and len(same_list) < 13:        for j in range(0, len(same_list), 2):                if count < int(args.num_samepairs):#數量可以修改                    dst.writelines(same_list[j] + ' ' + same_list[j+1]+ ' ' + '1' + '\n')                    count += 1    if count >= int(args.num_samepairs):        breaklist2 = list1.copy()# 產生不同的影象對diff = 0print(count)# 如果不同的影象對遠遠小於相同的影象對,則繼續重複產生,直到兩者相差很小while True:    random.seed(time.time() * 100000 % 10000)    random.shuffle(list2)    for p in range(0, len(list2) - 1, 2):        if list2[p] != list2[p + 1]:            dst.writelines(list2[p] + ' ' + list2[p + 1] + ' ' + '0'+ '\n')            diff += 1            if diff >= count:                break            #print(diff)    if diff < count:        #print('--')        continue    else:        break

執行generate_image_pairs.py

python3 generate_image_pairs.py --data-dir ../../datasets/output --outputtxt ../../datasets/train/train.txt --num-samepairs 5

--data-dir 後接對齊後的人臉

--outputtxt 用於儲存train.txt檔案

--num-samepairs 生成多少對(具體如何設定,還需要好好研究一下)

執行成功後在datasets/train下會生成一個train.txt檔案

內容:

../../datasets/output/Abdullah/Abdullah_0002.jpg ../../datasets/output/Abdullah/Abdullah_0004.jpg 1# 前面兩個分佈是生成的pairs的路徑,後面的0/1代表是否同一個人或類

(5)生成驗證集bin檔案

成功後利用/src/data/下的 lfw2pack.py生成bin檔案

但是存在點問題,對lfw2pack.py進行稍微的修改,修改lfw2pack.py中19行,打#的為更改的,改為兩個引數,一個是txt讀出來的列表,另一個是總數量。

import mxnet as mxfrom mxnet import ndarray as ndimport argparseimport pickleimport sysimport ossys.path.append(os.path.join(os.path.dirname(__file__), '..', 'eval'))import lfwparser = argparse.ArgumentParser(description='Package LFW images')# generalparser.add_argument('--data-dir', default='', help='')# 修改1:影象大小修改為112,112parser.add_argument('--image-size', type=str, default='112,112', help='')parser.add_argument('--output', default='', help='path to save.')# 修改2:新增解析引數 parser.add_argument('--num-samepairs',default=100)args = parser.parse_args()lfw_dir = args.data_dirimage_size = [int(x) for x in args.image_size.split(',')]# 修改3:將檔名pairs.txt修改成train.txtlfw_pairs = lfw.read_pairs(os.path.join(lfw_dir, 'train.txt'))print(lfw_pairs)# 修改4:下一行進行修改成需要的格式# lfw_paths, issame_list = lfw.get_paths(lfw_dir, lfw_pairs, 'jpg')lfw_paths, issame_list = lfw.get_paths(lfw_pairs,int(args.num_samepairs)+1)#, 'jpg')lfw_bins = []#lfw_data = nd.empty((len(lfw_paths), 3, image_size[0], image_size[1]))print(len(issame_list))i = 0for path in lfw_paths:  with open(path, 'rb') as fin:    _bin = fin.read()    lfw_bins.append(_bin)    #img = mx.image.imdecode(_bin)    #img = nd.transpose(img, axes=(2, 0, 1))    #lfw_data[i][:] = img    i+=1    if i%1000==0:      print('loading lfw', i)with open(args.output, 'wb') as f:  pickle.dump((lfw_bins, issame_list), f, protocol=pickle.HIGHEST_PROTOCOL)

對應的get_paths這個檔案存在src/eval/lfw.py下,把它也改了

def get_paths(pairs, same_pairs):    nrof_skipped_pairs = 0    path_list = []    issame_list = []    cnt = 1    for pair in pairs:      path0 = pair[0]      path1 = pair[1]      if cnt < same_pairs:        issame = True      else:        issame = False       if os.path.exists(path0) and os.path.exists(path1):    # Only add the pair if both paths exist        path_list += (path0,path1)        issame_list.append(issame)      else:        print('not exists', path0, path1)        nrof_skipped_pairs += 1      cnt += 1    if nrof_skipped_pairs>0:        print('Skipped %d image pairs' % nrof_skipped_pairs)    return path_list, issame_list

vim中多行註釋方法:

多行註釋:1. 進入命令列模式,按ctrl + v進入 visual block模式,然後按j, 或者k選中多行,把需要註釋的行標記起來2. 按大寫字母I,再插入註釋符,例如 #3. 按esc鍵就會全部註釋了取消多行註釋:1. 進入命令列模式,按ctrl + v進入 visual block模式,按字母l橫向選中列的個數,例如 # 需要選中2列2. 按字母j,或者k選中註釋符號3. 按d鍵就可全部取消註釋

之後再執行

python3 lfw2pack.py --data-dir ../../datasets/train --output ../../datasets/train/lfw.bin --num-samepairs 2

注意:我這裡報錯了(沒有報錯的小夥伴可以忽略)

至此,我們已經完成了資料集的製作,後續會更新如何訓練,以及使用。

參考連結:

https://blog.csdn.net/CLOUD_J/article/details/100672392

https://blog.csdn.net/hanjiangxue_wei/article/details/86566497

27
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 專案中建立多少執行緒合適?