python人臉識(shí)別與特征描繪

實(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)用,主要由兩種方法。

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

畫圖

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í)別與特征描繪
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容