也許是最簡單的人臉識別

啰唆幾句

最近在研究人臉探測,人臉驗證,人臉識別。在理論知識補充后就是要自己動手寫code了。在寫code之前基于不做“重復(fù)工作”的懶人思想在網(wǎng)上搜索了下現(xiàn)有的人臉識別開源項目,在對比過幾種方法后發(fā)現(xiàn)了face_recognition這個項目,該項目使用dlib作為人臉探測,而在face_recognition中也提供了兩種探測方式:HOG和CNN。探測到人臉后提取128維面部特征,這128維的數(shù)據(jù)作為一個unknown的嵌入(embedding)和已知(標(biāo)記)的嵌入進行相似度比較,在接受的閾值范圍內(nèi)認定是同一個人,雖然其頁面上沒有詳細說明是怎樣判定距離的,從其程序運行反饋的一些結(jié)果上我猜測是使用了Siamese network。face_recognition雖然使用十分簡單,但還是有一些概念需要提一下:

  • HOG
    剛才已經(jīng)提到HOG是face_recognition使用的一種面部探測的方式,HOG是Histogram of Oriented Gradients的簡稱也就是方向梯度直方圖。
  • CNN
    基于卷積神經(jīng)網(wǎng)絡(luò)的探測臉的方式原則上會比HOG的準(zhǔn)確度高,其原理我會記錄在后續(xù)的理論文章中,大致理解就是使用一個bounding box去掃描整張圖片并查看每一個bounding box中是否有目標(biāo)對象
  • 其他
    除了上述兩種人臉探測的方式還有不少其他的方式比如opencv中所采用的Haar Cascades,其實用了adaboost的方法來分類(熟悉機器學(xué)習(xí)的朋友會心一笑,懂了。。。),但其效果理論上是比不上CNN的。當(dāng)然也有更精確的人臉探測方式Multi-task CNN,在git上也有其python的實現(xiàn)facenet。

實現(xiàn)步驟

啰嗦了這么多我們來看下怎么快速的實現(xiàn)一個人臉識別

  • dlib
    dlib是關(guān)鍵,ubuntu和win上的安裝很簡單,先說ubuntu吧
    • ubuntu

apt-get install -y --fix-missing
build-essential
cmake
gfortran
git
wget
curl
graphicsmagick
libgraphicsmagick1-dev
libatlas-dev
libavcodec-dev
libavformat-dev
libgtk2.0-dev
libjpeg-dev
liblapack-dev
libswscale-dev
pkg-config
python3-dev
python3-numpy
software-properties-common
zip
&& apt-get clean

這樣dlib所需的Cmake和boost就安裝好了

mkdir -p dlib
git clone -b 'v19.9' --single-branch https://github.com/davisking/dlib.git dlib/
cd dlib
python setup.py install --yes USE_AVX_INSTRUCTIONS

以上就在ubuntu的環(huán)境中安裝好了dlib,可以進入python 然后import dlib嘗試下。

  • win

mkdir CMAKE
cd CMAKE
cmake -G "Visual Studio 14 2015 Win64" -T host=x64 ..
cmake --build . --config Release

然后下載dlib,進入其folder

python setup.py install

在dlib安裝好以后安裝face_recognition

pip install face_recognition

開始人臉識別

import face_recognition
from PIL import Image, ImageDraw
#已知(標(biāo)記)人臉照片讀取
1_image = face_recognition.load_image_file("1.jpg")
1_face_encoding = face_recognition.face_encodings(1_image)[0]
2_image = face_recognition.load_image_file("2.jpg")
2_face_encoding = face_recognition.face_encodings(2_image)[0]
#embedding
known_face_encodings = [
   1_face_encoding,
   2_face_encoding
    ]
known_face_names = [
    "張三",
    "李四"
]
#輸入未標(biāo)記的照片
unknown_image = face_recognition.load_image_file("unknown.jpg")
unknown_face_locations = face_recognition.face_locations(unknown_image)
# unknown_face_locations = face_recognition.face_locations(unknown_image,number_of_times_to_upsample=0, model="cnn")如果電腦有N卡并安裝了cuda,使用cnn
unknown_face_encodings = face_recognition.face_encodings(unknown_image, unknown_face_locations)
pil_image = Image.fromarray(unknown_image)
draw = ImageDraw.Draw(pil_image)
# 探測人臉并和已知人臉比對
for (top, right, bottom, left), unknown_face_encoding in zip(unknown_face_locations, unknown_face_encodings):
    matches = face_recognition.compare_faces(known_face_encodings, unknown_face_encoding,tolerance=0.4)
    # distance = face_recognition.face_distance(known_face_encodings, unknown_face_encoding)
    print(matches)
    name = "Unknown"
    if True in matches:
        first_match_index = matches.index(True)
        name = known_face_names[first_match_index]        
   #if 之后代碼部分能優(yōu)化成選取distance小于tolerance中的最小的一個值

  #draw bounding box并標(biāo)記
    draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
    text_width, text_height = draw.textsize(name)
    draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
    draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))

del draw

pil_image.show()

上述就實現(xiàn)了一個人臉識別,由于手頭素材涉及同事照片就不把識別結(jié)果分享出來了,我個人實現(xiàn)的實際效果還不錯。

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容