python人脸识别与特征描绘

实时人脸检测月特征描绘.gif

本文目录

介绍
part 1 安装依赖
  - 安装dlib
  - 安装 python 人脸识别库 face_recognition

part 2 图片、视频操作
  - 读取图片
  - 读取、保存视频
  - 画图

part 3 模型实践:人脸识别与特征描绘
(face_recognition + PIL + numpy)

介绍

人脸识别只是物体识别中的特殊应用,主要由两种方法。

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()

画图

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()
人脸识别与特征描绘
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容