實(shí)時(shí)人臉檢測(cè)月特征描繪.gif
本文目錄
介紹
part 1 安裝依賴
- 安裝dlib
- 安裝 python 人臉識(shí)別庫(kù) face_recognition
part 2 圖片、視頻操作
- 讀取圖片
- 讀取、保存視頻
- 畫圖
part 3 模型實(shí)踐:人臉識(shí)別與特征描繪
(face_recognition + PIL + numpy)
介紹
人臉識(shí)別只是物體識(shí)別中的特殊應(yīng)用,主要由兩種方法。
- HOG(Histogram of Oriented Gradients?),主要思路是根據(jù)圖片像素點(diǎn)級(jí)別的亮暗變化,畫出物體輪廓,完成物體邊緣檢測(cè)。該方法可用于人臉識(shí)別,opencv與dlib都提供有相關(guān)ptyhon接口。
論文《Histograms of Oriented Gradients for Human Detection》
ageitgey博客,人臉識(shí)別原理介紹
《Histograms of Oriented Gradients for Human Detection》中的圖片 - 利用深度學(xué)習(xí),效果有不小提升。HOG對(duì)正面的人臉識(shí)別效果好些,但基于深度學(xué)習(xí)的識(shí)別各方面都很優(yōu)秀。dlib支持基于深度學(xué)習(xí)模型的人臉識(shí)別支持C++與python。
知乎問題:為什么香港中文大學(xué)研發(fā)的人臉識(shí)別算法能夠擊敗人類?
知乎專欄:基于深度學(xué)習(xí)的人臉識(shí)別技術(shù)綜述
論文《Face Detection with the Faster R-CNN》
dlib開源項(xiàng)目 python_examples/cnn_face_detector
效果對(duì)比:HOG藍(lán)色框框、深度學(xué)習(xí)CNN紅色框框
part 1 安裝依賴
安裝 dlib
# 方法一 pip
pip install dlib
# 方法二 python編譯,進(jìn)入dlib文件夾
git clone https://github.com/davisking/dlib.git
cd dlib
python setup.py install 或
python setup.py install --yes USE_AVX_INSTRUCTIONS --yes DLIB_USE_CUDA # 可選,如果 CPU支持AVX或有Nvidia GPU
# 方法三 CMake 和 boost-python 編譯
##(1) 安裝依賴
sudo apt-get install libboost-python-dev cmake # ubuntu機(jī)器
pip install scikit-image # python example 需要依賴scikit-image
##(2)編譯
git clone https://github.com/davisking/dlib.git # clone代碼
cd dlib
mkdir build
cd build
cmake .. -DDLIB_USE_CUDA=0 -DUSE_AVX_INSTRUCTIONS=1
cmake --build .
##(3)安裝
cd ..
python setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA
過程中可能遇到的error ,參考 dlib github issues
執(zhí)行: python2 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA
報(bào)錯(cuò): c++: internal compiler error: Killed (program cc1plus)
原因: 內(nèi)存不足
方案: 調(diào)整虛擬機(jī)內(nèi)存,或提升交換內(nèi)存
更多的dlib編譯安裝參考資料,mac與linux的dlib安裝教程
安裝 python 人臉識(shí)別庫(kù) face_recognition
face_recognition主要對(duì)dlib進(jìn)行了封裝,為了更便于使用。
# 完成以上依賴的安裝后
pip install face_recognition
過程中可能遇到的error ,參考 face_recognition github issues
執(zhí)行: pip install face_recognition
報(bào)錯(cuò): MemoryError
原因: The face_recognition_models file is too big for your available pip cache memory.
方案: 執(zhí)行 pip --no-cache-dir install face_recognition
part 2 圖片、視頻操作
讀取圖片
更多通過url讀取圖片的方法參考這里
# 方法一 skimage,支持本地與url讀取網(wǎng)絡(luò)圖片,shape為 (height, weight, RGB), type為uint8
from skimage import io
image = io.imread(url) # 此處url也可以為本地path
io.imshow(image)
io.show()
# 方法二 scipy.misc,支持本地圖片,shape為 (height, weight, RGB), type為uint8
import scipy.misc
image = scipy.misc.imread(TEST_IMAGE_PATHS[0], mode='RGB')
# 方法三 opencv,支持本地圖片; 但格式為 BRG
import cv2
image = cv2.imread(path)
image = image[...,::-1] # BRG轉(zhuǎn)換為RBG格式
讀取、保存視頻
opencv 支持?jǐn)z像頭、本地與url網(wǎng)絡(luò)視頻,opencv Getting Started with Videos
# 攝像頭 (低效讀視頻)
import cv2
video_capture = cv2.VideoCapture(0)
while True:
ret, frame = video_capture.read()
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'): # 在播放窗口,點(diǎn)擊q退出
break
video_capture.release()
cv2.destroyAllWindows()
# 保存視頻
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
out.write(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
以上方法視頻讀取效率低,可以用于調(diào)試。更高效的方法是使用“多線程+opencv”,效果體現(xiàn)在 fps(frame per second)的提高。參考 Increasing webcam FPS with Python and OpenCV
import cv2
from threading import Thread
# 多線程,高效讀視頻
class WebcamVideoStream:
def __init__(self, src, width, height):
# initialize the video camera stream and read the first frame
# from the stream
self.stream = cv2.VideoCapture(src)
self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
(self.grabbed, self.frame) = self.stream.read()
# initialize the variable used to indicate if the thread should
# be stopped
self.stopped = False
def start(self):
# start the thread to read frames from the video stream
Thread(target=self.update, args=()).start()
return self
def update(self):
# keep looping infinitely until the thread is stopped
while True:
# if the thread indicator variable is set, stop the thread
if self.stopped:
return
# otherwise, read the next frame from the stream
(self.grabbed, self.frame) = self.stream.read()
def read(self):
# return the frame most recently read
return self.frame
def stop(self):
# indicate that the thread should be stopped
self.stopped = True
# 使用方法
video_capture = WebcamVideoStream(src=video_source,
width=width,
height=height).start()
frame = video_capture.read()
畫圖
- opencv 提供了豐富的方法看這里
import cv2
image = cv2.imread(path)
# 調(diào)整圖片大小為原來的1/4
small_frame = cv2.resize(image, (0, 0), fx=0.25, fy=0.25)
# 畫長(zhǎng)方形
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) # 中間無填充顏色
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED) # 中間填充顏色
# 畫多邊形
cv2.polylines(black_image, [left_eye], True, color, thickness)
# 寫字
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'): # 在播放窗口,點(diǎn)擊q退出
break
- pillow庫(kù) 提供了豐富的方法看這里
from PIL import Image, ImageDraw
pil_image = Image.fromarray(image) # image 為 np.ndarray
d = ImageDraw.Draw(pil_image)
d.line(face_landmarks[facial_feature], width=5) # 畫線
d.rectangle(xy=[(left, top), (right, bottom)], outline=(255, 0, 0)) #
畫長(zhǎng)方形
pil_image.thumbnail(image.shape * np.array(0.5), Image.ANTIALIAS) # 改變尺寸
pil_image.show()
part 3 模型實(shí)踐:人臉識(shí)別與特征描繪(face_recognition + PIL + numpy)
# -*- coding: utf-8 -*-
import face_recognition
from PIL import Image, ImageDraw
import numpy as np
facial_features = ['chin','left_eyebrow','right_eyebrow','nose_bridge','nose_tip','left_eye','right_eye','top_lip','bottom_lip']
image = face_recognition.load_image_file("test15.jpg") # 讀圖片
face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=1) # 人臉定位
face_landmarks_list = face_recognition.face_landmarks(image, face_locations) # 人臉特征點(diǎn)識(shí)別
# 圖片處理、展示
pil_image = Image.fromarray(image)
d = ImageDraw.Draw(pil_image)
for (top, right, bottom, left), face_landmarks in zip(face_locations, face_landmarks_list):
# 描繪臉部特征
for facial_feature in facial_features:
d.line(face_landmarks[facial_feature], width=5)
# 框住人臉
d.rectangle(xy=[(left, top), (right, bottom)], outline=(255, 0, 0))
# 改變圖片大小,縮小為原來的1/2
pil_image.thumbnail(image.shape * np.array(0.5), Image.ANTIALIAS)
pil_image.show()
人臉識(shí)別與特征描繪