本文目录
介绍
part 1 安装依赖
- 安装dlib
- 安装 python 人脸识别库 face_recognition
part 2 图片、视频操作
- 读取图片
- 读取、保存视频
- 画图
part 3 模型实践:人脸识别与特征描绘
(face_recognition + PIL + numpy)
介绍
人脸识别只是物体识别中的特殊应用,主要由两种方法。
- HOG(Histogram of Oriented Gradients ),主要思路是根据图片像素点级别的亮暗变化,画出物体轮廓,完成物体边缘检测。该方法可用于人脸识别,opencv与dlib都提供有相关ptyhon接口。
论文《Histograms of Oriented Gradients for Human Detection》
ageitgey博客,人脸识别原理介绍
- 利用深度学习,效果有不小提升。HOG对正面的人脸识别效果好些,但基于深度学习的识别各方面都很优秀。dlib支持基于深度学习模型的人脸识别支持C++与python。
知乎问题:为什么香港中文大学研发的人脸识别算法能够击败人类?
知乎专栏:基于深度学习的人脸识别技术综述
论文《Face Detection with the Faster R-CNN》
dlib开源项目 python_examples/cnn_face_detector
part 1 安装依赖
安装 dlib
# 方法一 pip
pip install dlib
# 方法二 python编译,进入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机器
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
执行: python2 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA
报错: c++: internal compiler error: Killed (program cc1plus)
原因: 内存不足
方案: 调整虚拟机内存,或提升交换内存
更多的dlib编译安装参考资料,mac与linux的dlib安装教程
安装 python 人脸识别库 face_recognition
face_recognition主要对dlib进行了封装,为了更便于使用。
# 完成以上依赖的安装后
pip install face_recognition
过程中可能遇到的error ,参考 face_recognition github issues
执行: pip install face_recognition
报错: MemoryError
原因: The face_recognition_models file is too big for your available pip cache memory.
方案: 执行 pip --no-cache-dir install face_recognition
part 2 图片、视频操作
读取图片
更多通过url读取图片的方法参考这里
# 方法一 skimage,支持本地与url读取网络图片,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转换为RBG格式
读取、保存视频
opencv 支持摄像头、本地与url网络视频,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'): # 在播放窗口,点击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()
以上方法视频读取效率低,可以用于调试。更高效的方法是使用“多线程+opencv”,效果体现在 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)
# 调整图片大小为原来的1/4
small_frame = cv2.resize(image, (0, 0), fx=0.25, fy=0.25)
# 画长方形
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'): # 在播放窗口,点击q退出
break
- pillow库 提供了丰富的方法看这里
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)) #
画长方形
pil_image.thumbnail(image.shape * np.array(0.5), Image.ANTIALIAS) # 改变尺寸
pil_image.show()
part 3 模型实践:人脸识别与特征描绘(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) # 人脸特征点识别
# 图片处理、展示
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()