張值銘 楊德剛
摘? 要:深度學(xué)習(xí)的訓(xùn)練往往需要用到大量數(shù)據(jù),但目前主要是以部分著名開源的數(shù)據(jù)集為主。其中開源的人臉數(shù)據(jù)集大多是基于西方人種,缺乏多樣性。針對以上問題,提出一種人臉數(shù)據(jù)集制作方法,用于后續(xù)訓(xùn)練和研究。文章讓計(jì)算機(jī)承擔(dān)大部分工作,可以極大減輕人工收集制作以及篩選中耗費(fèi)的時(shí)間精力,準(zhǔn)確率高、不規(guī)范圖片少,是一種可行的人臉數(shù)據(jù)集收集制作方法。
關(guān)鍵詞:爬蟲;OpenCV庫;數(shù)據(jù)集;人臉;dlib庫
中圖分類號:TP391? ? 文獻(xiàn)標(biāo)識碼:A? ? 文章編號:2096-4706(2020)18-0098-06
Abstract:Deep learning training often needs to use a lot of data,but at present it is mainly based on some famous open source data sets. Most of the open source face data sets are based on the Western race,and lack of diversity. In view of the above problems,a method of making face data set is proposed for subsequent training and research. In this paper,let the computer undertake most of the work,which can greatly reduce the time and energy consumed in the manual collection and production and screening,with high accuracy and less nonstandard images. It is a feasible method of face data collection and production.
Keywords:crawler;OpenCV library;datasets;face;dlib library
0? 引? 言
人臉數(shù)據(jù)集是一種通過僅對人物圖像的面部區(qū)域進(jìn)行切割形成的數(shù)據(jù)集,被廣泛用于人臉識別[1],人臉生成對抗[2]等神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練,目前著名人臉數(shù)據(jù)集往往基于西方人種,如CelebA[3]人臉數(shù)據(jù)集等,缺乏對亞裔人種的支持,而兩者人臉特征存在較大差異,不利于在亞裔人群的使用場景中對模型進(jìn)行優(yōu)化,因此需要進(jìn)行針對性的亞裔人臉數(shù)據(jù)集制作。作者通過在學(xué)校的服務(wù)器上制作亞裔人臉數(shù)據(jù)集為后續(xù)的人臉打卡系統(tǒng),宿舍人臉門禁系統(tǒng)等實(shí)驗(yàn)的研究提供基礎(chǔ)訓(xùn)練數(shù)據(jù)。
傳統(tǒng)采集數(shù)據(jù)集的方式主要為人工進(jìn)行拍攝后再進(jìn)行后期加工,費(fèi)時(shí)費(fèi)力,且數(shù)據(jù)集的容量往往不足以用于深度學(xué)習(xí)訓(xùn)練,因此急需一種在低人工成本的前提下,可以大量采集并且可以精確定位并裁剪人臉部分的人臉數(shù)據(jù)集收集和制作方法。
1? 相關(guān)技術(shù)介紹
1.1? 爬蟲模塊
爬蟲[4]是一種按照一定目的在互聯(lián)網(wǎng)上自動獲取對應(yīng)信息或資源的技術(shù)。爬蟲往往偽裝成正常的瀏覽器,并通過向目標(biāo)網(wǎng)站發(fā)起請求,獲取對應(yīng)資源或信息后進(jìn)行有目的的存儲或分析,如搜索引擎,通過向互聯(lián)網(wǎng)進(jìn)行信息抓取提取和存儲,為用戶進(jìn)行搜索提供便利。
本文使用的是基于Python語言的爬蟲技術(shù),Python是一種提供各類第三方工具包的高級腳本語言,其中本文用于爬蟲的工具包有Requests,Beautiful Soup。Requests[5]是一種著名的開源Python HTTP第三方庫,該庫的優(yōu)勢在于遵循PEP 20開發(fā)準(zhǔn)則,API具有較高的可讀性,優(yōu)雅簡潔等特點(diǎn),比Python自帶的urllib和urllib2更靈活,使得開發(fā)人員更容易使用,Requests庫可以實(shí)現(xiàn)對服務(wù)器發(fā)出get或者post請求以及接收響應(yīng),該庫還可以通過傳遞請求頭參數(shù)模擬瀏覽器,使用代理等方式來規(guī)避反爬蟲策略,本文選用Requests并使用并發(fā)的方式進(jìn)行爬取,可以有效地實(shí)現(xiàn)目的。Beautiful Soup 5[6]是一種網(wǎng)頁解析庫,該庫主要用于分析網(wǎng)頁信息,支持多種格式,如HTML,XML等,該庫可以方便地將獲取的網(wǎng)頁結(jié)構(gòu)化,并提供了一系列方法方便開發(fā)者方便的定位和獲取目標(biāo)內(nèi)容。
1.2? OpenCV模塊
OpenCV[7]是一種跨平臺的開源的計(jì)算機(jī)視覺和圖像處理庫,該庫由C++語言編寫而成,同時(shí)提供了多種語言接口,本文使用其Python接口。該庫應(yīng)用領(lǐng)域廣泛,如邊緣檢測,三維重建,圖像分割等。其中CascadeClassifier是OpenCV中用于目標(biāo)檢測的級聯(lián)分類器,該分類器通過使用局部二值特征(Local Binary Pattern,LBP)導(dǎo)入特定的分類器文件,如人臉分類器haarcascade_frontalface_alt.xml,可以實(shí)現(xiàn)對人臉的檢測。如圖1所示,其中矩形框部分為使用此分類器后標(biāo)注的人臉位置。
1.3? dlib模塊
dlib[8]是一種包含多種機(jī)器學(xué)習(xí)算法以及工具的開源庫,該庫基于C++語言編寫,同樣支持Python接口,該庫在學(xué)術(shù)以及工業(yè)領(lǐng)域有著廣泛的應(yīng)用。該庫包含如深度學(xué)習(xí)算法,多分類支持向量機(jī)[9],以及多種聚類算法等,也包含一些圖像處理工具,比如常見的圖像操作工具邊緣查找,形態(tài)學(xué)工具等,甚至還包括一些網(wǎng)絡(luò)方面的工具,如簡單的HTTP服務(wù)器對象,以及TCP Socket API等。其中g(shù)et_frontal_face_detector為dlib的人臉檢測器函數(shù),若輸入圖片不包含人臉則該函數(shù)返回為空。本文使用此函數(shù)進(jìn)行對人臉的篩選。
2? 項(xiàng)目分析與設(shè)計(jì)
2.1? 項(xiàng)目分析
本項(xiàng)目需要實(shí)現(xiàn)對人物圖片網(wǎng)站的爬取,存儲到硬盤中,然后將人臉部分切割出來并保存,實(shí)現(xiàn)人臉數(shù)據(jù)集的制作。在此過程中最重要的目的是在保證質(zhì)量和速度的前提下降低人工復(fù)檢的難度,也就是使用程序處理的結(jié)果只能包含極少量的非人臉圖片,因此本文必須設(shè)計(jì)篩選模塊。
2.1.1? 爬蟲過程分析
項(xiàng)目首先需要實(shí)現(xiàn)對人物圖像網(wǎng)站的爬取,對不同類型人群的人臉數(shù)據(jù)集制作則需要找到對應(yīng)目標(biāo)網(wǎng)站,目的在于將該網(wǎng)站上所有亞裔人物圖像保存到硬盤中,用于后續(xù)的處理,同時(shí)由于單線程會在數(shù)據(jù)寫入,數(shù)據(jù)分析,等待服務(wù)器響應(yīng)等過程耗費(fèi)較多時(shí)間,無法充分利用帶寬,因此本文將使用多線程的方式進(jìn)行爬取,爬取的速度主要取決于帶寬上限。
本文以wallhavean為例,首先進(jìn)行網(wǎng)頁分析,打開wallhaven主頁:https://wallhaven.cc/,搜索asian people,會跳到亞洲人物圖片網(wǎng)頁:https://wallhaven.cc/search?q=id%3A449&categories=001&purity=100&sorting=relevance&order=desc&page=2,如圖2所示。
通過測試,發(fā)現(xiàn)其中網(wǎng)址中的page是對應(yīng)網(wǎng)頁編號,使用for循環(huán)即可遍歷該網(wǎng)站所有頁面,使用火狐瀏覽器F12開發(fā)者工具,可以定位到每個頁面中圖片的href屬性值,如圖3所示。
其網(wǎng)頁DOM中a標(biāo)簽的href屬性值為該圖片預(yù)覽圖地址,打開該網(wǎng)址,可以發(fā)現(xiàn)跳轉(zhuǎn)到了一個新的頁面,如圖4所示。
對該頁面中出現(xiàn)的大圖進(jìn)行定位,發(fā)現(xiàn)該圖的src地址為:https://w.wallhaven.cc/full/qd/wallhaven-qdr6w5.jpg,通過訪問此地址,確認(rèn)為最終的圖片地址,只要對該地址進(jìn)行請求即可完成目標(biāo)圖片的下載,圖5為最終的高清大圖。
2.1.2? 人臉處理過程分析
對爬蟲保存的所有人物圖片進(jìn)行處理,使用OpenCV的級聯(lián)分類器,對保存下來的人物圖片進(jìn)行面部識別,并將面部進(jìn)行切割保存,同時(shí)由于僅使用OpenCV在進(jìn)行人臉識別時(shí)的準(zhǔn)確率不夠高,在原始圖像足夠多的情況下將產(chǎn)生大量不包含人臉部分的圖片,因此使用dlib模塊進(jìn)行篩選,去掉不合格的部分。
2.2? 項(xiàng)目設(shè)計(jì)
項(xiàng)目設(shè)計(jì)包含四個方面,第一是使用爬蟲進(jìn)行圖像收集,第二個是人臉識別模塊,使用OpenCV模塊實(shí)現(xiàn)對人臉的裁剪,第三個是篩選模塊,使用dlib模塊對裁剪的圖像進(jìn)行篩選,去除不合格圖片,最后是人工復(fù)檢。具體流程如圖6所示。
2.3? 項(xiàng)目部分代碼
2.3.1? 爬蟲部分代碼
作者通過在學(xué)校實(shí)驗(yàn)室服務(wù)器上運(yùn)行home/lab/cqnu/face/spyder.py腳本,實(shí)現(xiàn)對目標(biāo)網(wǎng)站的請求與網(wǎng)頁分析,獲取目標(biāo)圖片的完整url地址,并以多線程的方式實(shí)現(xiàn)對圖片的爬取,其中部分代碼為:
#此函數(shù)實(shí)現(xiàn)對wallheaven頁面的請求,通過偽裝成瀏覽器獲取頁面信息
def request_url(page):
url='https://wallhaven.cc/search?q=id%3A449&categories=001&purity=100&sorting=relevance&order=desc&page={}'.format(str(page))
#此處傳遞不同的page參數(shù)可以實(shí)現(xiàn)請求不同的網(wǎng)頁
headers = {'User-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36','Referer':url,'Host':'wallhaven.cc'}
#請求頭參數(shù),包含瀏覽器偽裝,Referer,以及Host,其中User-Agent用于偽裝成Windows系統(tǒng)下的谷歌瀏覽器,為常見的反爬蟲策略
time.sleep(random.randint(1,10))#此項(xiàng)為程序隨機(jī)休眠,為防止同一時(shí)間大量的請求被服務(wù)器認(rèn)為是爬蟲
r=requests.get(url,headers=headers)#向服務(wù)器發(fā)出請求
if not r.status_code==200:#此處為判斷返回狀態(tài)碼,狀態(tài)為200代表正常,非200則結(jié)束函數(shù)
print(url,'status code error ',r.status_code)
return
r.encoding='gb2312'
r_text=r.text
r.close()#結(jié)束時(shí)關(guān)閉連接
return r_text#返回網(wǎng)頁數(shù)據(jù)
#此部分函數(shù)實(shí)現(xiàn)對頁面的分析,定位并找到高清圖片的url地址
def soup(r_text):
if not r_text:
print('soup is None')
return
#此處為判斷網(wǎng)頁數(shù)據(jù)是否為空,如果為空,則結(jié)束函數(shù)
soup=BeautifulSoup(r_text,'html.parser')#使用beautiful soup進(jìn)行網(wǎng)頁數(shù)據(jù)分析
a_list=soup.find_all('a',class_='preview')#定位該網(wǎng)頁中縮略圖的位置
md5_text_list=[]#此數(shù)組為存儲縮略圖url中的特征字段
md5_text=a['href'].split('/')[-1]
fullPic_url_list=[]
for a in a_list:
md5_text=a['href'].split('/')[-1]#此項(xiàng)為特征字段,如eodqxl,為后續(xù)構(gòu)成完整高清圖像url的關(guān)鍵
md5_text_list.append(md5_text)
#print(md5_text)
fullPic_url='https://w.wallhaven.cc/full/{}/wallhaven-{}.jpg'.format(md5_text[:2],md5_text)
#print(fullPic_url)#打印完整高清圖像url,其中第一個大括號為特征字段的前兩個字符,如eodqxl的前兩個字符為eo
#https://w.wallhaven.cc/full/qd/wallhaven-qdr6w5.jpg
fullPic_url_list.append(fullPic_url)
#print(fullPic_url_list)#打印該頁所有圖像的完整url地址
#返回特征字段,作為后續(xù)保存文件的文件名,返回完整圖像的url地址
return md5_text_list,fullPic_url_list
#此函數(shù)用于下載圖像并保存到硬盤中
def download(file_name,fullPic_url):
#保存圖片的文件夾絕對路徑,若不存在則創(chuàng)建該文件夾
root_dir=os.path.join('home/lab/cqnu/face/data/pic')
if not os.path.exists(root_dir):
os.makedirs(root_dir)
#此項(xiàng)為判斷文件是否存在,若存在則無需進(jìn)行下面服務(wù)器請求等步驟,直接停止
file_path=os.path.join(root_dir,file_name+'.jpg')
if os.path.exists(file_path):
print('{} 已存在'.format(file_path))
return
headers={'User-agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36','Host':'w.wallhaven.cc'}
r=requests.get(fullPic_url,stream=True,headers=headers)#向服務(wù)器發(fā)出請求
time.sleep(random.randint(1,10))#隨機(jī)休眠
if not r.status_code==200:
print('{} is wrong!status code error {}'.format(fullPic_url,r.status_code))
return 1
#返回狀態(tài)碼非200則停止函數(shù)
with open(file_path,'wb') as f:
print('正在寫入 :{}'.format(file_path))
for chunk in r.iter_content(chunk_size=8192):
#使用流式的方式進(jìn)行下載時(shí),將最大的字節(jié)流設(shè)置成8192,可以實(shí)現(xiàn)一邊下載一邊存儲
if chunk:
f.write(chunk)
f.flush()
r.close()#關(guān)閉連接
#此函數(shù)為封裝以上過程,方便后續(xù)使用多線程
def run_download(page):
r_text=request_url(page)
md5_text_list,fullPic_url_list=soup(r_text)
if not fullPic_url_list:
return
for md5_text,fullPic_url in zip(md5_text_list,fullPic_url_list):
download(md5_text,fullPic_url)
print('page %s download over'%str(page))#當(dāng)每頁下載完成后,打印此信息
if __name__=='__main__':
for page in range(1,435):
p=Thread(target=run_download,args=(page,))#此處為使用多線程的方式進(jìn)行爬取,傳入page參數(shù)即可
p.start()
2.3.2? 人臉分割部分代碼
編輯/home/lab/cqnu/face/detect.py腳本實(shí)現(xiàn)人臉檢測與分割,并將分割后的人臉進(jìn)行保存,其中部分代碼為:
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')#加載默認(rèn)人臉檢測分類器
img = cv2.imread(src_img_path)#讀取圖片
faces = face_cascade.detectMultiScale(img,1.3,5)#獲取人臉坐標(biāo)位置
for (x,y,w,h) in faces:#臉部的坐標(biāo)數(shù)據(jù),包括x,y坐標(biāo)以及寬高
face_result = img[y:y+h, x:x+w]#根據(jù)坐標(biāo)獲取人臉?biāo)诘木匦慰騼?nèi)的像素?cái)?shù)據(jù)
cv2.imwrite('face.jpg',face_result)#保存人臉圖片
2.3.3? 檢測部分代碼
編輯/home/lab/cqnu/face/check.py腳本實(shí)現(xiàn)對人臉圖片的檢測,并將所有不合格的圖片移除。其中部分代碼為:
def detect_face(img_path,detector):
img=cv2.imread(img_path)
detector = dlib.get_frontal_face_detector()#加載dlib人臉檢測方法
if detector(img,0):
#此處返回一個信號
#如果檢測到圖片包含人臉,則返回1,不處理
return 1
else:
#否則,返回0,進(jìn)行剪切操作。
return 0
def copy_remove(signal,img_path,img_name):
#此函數(shù)接收一個信號,然后進(jìn)行保存或剪切操作
trash_dir='home/lab/cqnu/face/data/trash'#非人臉部分的文件夾
if not signal:
#如果是丟棄信號,則將當(dāng)前圖片剪切到新文件夾
dst_path=os.path.join(trash_dir,img_name)
shutil.move(img_path,dst_path)
print('{} 未檢測到人臉,已剪切。'.format(img_name))#打印剪切掉的文件名
3? 實(shí)驗(yàn)對比
如表1所示,本文在依次使用OpenCV分割和dlib篩選后,進(jìn)行人工統(tǒng)計(jì),人臉總數(shù)占當(dāng)前總樣本數(shù)的比例。
其中在僅使用OpenCV后,發(fā)現(xiàn)有大量非人臉部分圖片,如圖7所示,隨后再使用dlib進(jìn)行篩選,雖然篩選的同時(shí)對部分人臉圖片誤刪除,圖8為丟棄的圖片,但最后剩下的人臉圖片中,僅含有極少量的不合格圖片,極大減輕了人工篩選的工作量,圖9為最終結(jié)果,證明了本文方法可行。
4? 結(jié)? 論
本文基于多線程爬蟲對某女性人物圖片網(wǎng)站進(jìn)行了數(shù)據(jù)收集,并對人臉部分進(jìn)行了切割和篩選,最終實(shí)現(xiàn)了人臉數(shù)據(jù)集的制作,證明了本文的可行性。在對其他人臉數(shù)據(jù)集的制作中,唯一有區(qū)別的就是爬蟲部分,需要對特定網(wǎng)站進(jìn)行有針對性的爬蟲代碼編寫。同時(shí)由于不同圖片的大小不一,所切割的臉部大小也可能不一樣,后續(xù)可以自行使用縮放算法統(tǒng)一人臉圖片尺寸。本文的不足之處在于使用dlib進(jìn)行篩選時(shí)誤刪了部分人臉圖像,如果在總體樣本較少的情況下可能會使得最終的數(shù)據(jù)集圖片數(shù)量偏少,這個過程的優(yōu)化有待日后做進(jìn)一步研究。
參考文獻(xiàn):
[1] 王碩.基于神經(jīng)網(wǎng)絡(luò)的人臉識別研究 [C]//第三十四屆中國(天津)2020IT、網(wǎng)絡(luò)、信息技術(shù)、電子、儀器儀表創(chuàng)新學(xué)術(shù)會議論文集.天津:天津市電子學(xué)會,2020:270-272.
[2] 仝宗和,劉釗.基于深度生成對抗網(wǎng)絡(luò)的模糊人臉增強(qiáng) [J].計(jì)算機(jī)應(yīng)用與軟件,2020,37(9):146-151+193.
[3] 李欣,張童,厚佳琪,等.基于深度學(xué)習(xí)的多角度人臉檢測方法研究 [J].計(jì)算機(jī)技術(shù)與發(fā)展,2020,30(9):12-17.
[4] 羅安然,林杉杉.基于Python的網(wǎng)頁數(shù)據(jù)爬蟲設(shè)計(jì)與數(shù)據(jù)整理 [J].電子測試,2020(19):94-95+31.
[5] 荀雪蓮,姚文彬.大數(shù)據(jù)網(wǎng)絡(luò)爬蟲技術(shù)在智慧圖書館信息資源建設(shè)上的應(yīng)用 [J].北華航天工業(yè)學(xué)院學(xué)報(bào),2020,30(4):20-22.
[6] 沈承放,莫達(dá)隆.beautiful soup庫在網(wǎng)絡(luò)爬蟲中的使用技巧及應(yīng)用 [J].電腦知識與技術(shù),2019,15(28):13-16.
[7] 廖周宇,王鈺婷,陳科良.基于OpenCV的人臉識別算法 [J].電子技術(shù)與軟件工程,2020(9):133-136.
[8] 王曉紅,韓嬌,李珊珊.基于人臉檢測器的實(shí)時(shí)視頻人臉檢測與跟蹤 [J].信息通信,2019(2):56-57.
[9] TAHA A,DARWISH A,HASSANIEN A E,et al. Arabian horse identification based on whale optimised multi-class support vector machine [J].International Journal of Computer Applications in Technology,2020,63(1-2):83-92.
作者簡介:張值銘(1994—),男,漢族,重慶人,碩士研究生,研究方向:機(jī)器學(xué)習(xí)、圖像處理;楊德剛(1976—),男,漢族,四川內(nèi)江人,教授,博士,研究方向:神經(jīng)網(wǎng)絡(luò)、圖像處理。