作者 |Juan Cruz Martinez
编译 |Flin
起源 |towardsdatascience
明天,咱们将学习如何检测图像中的人脸并提取面部特色,如眼睛、鼻子、嘴巴等。咱们能够将这些信息作为一个预处理步骤来实现,例如捕获照片中人物的人脸(手动或通过机器学习),创立成果来“加强”咱们的图像(相似于 Snapchat 等应用程序中的成果),对人脸进行情感剖析等等。
过来,咱们曾经探讨过如何应用 OpenCV 来检测图像中的形态,然而明天咱们将通过引入 DLib 和从图像中提取面部特色来将其晋升到一个新的程度。
- 相干浏览:
https://towardsdatascience.co…
Dlib 是一个高级的机器学习库,它是为解决简单的事实世界问题而创立的。这个库是用 C ++ 编程语言创立的,它与 C /C++、Python 和 java 一起工作。
- Dlib:http://dlib.net/
值得注意的是,本教程可能须要对 OpenCV 库有肯定的理解,例如如何解决图像、关上相机、图像处理和一些小技巧。
它是如何工作的?
咱们的脸有几个能够辨认的特色,比方眼睛、嘴巴、鼻子等等。当咱们应用 DLib 算法检测这些特色时,咱们实际上失去了每个特色的点的映射。
该映射由 67 个点(称为地标点)组成,可辨认以下特色:
- 颚点 = 0–16
- 右眉点 = 17–21
- 左眉点 = 22–26
- 鼻点 = 27–35
- 右眼点 = 36–41
- 左眼点 = 42–47
- 口角 = 48–60
- 嘴唇分数 = 61–67
当初让咱们来理解如何提取特色。
装置要求
与平常一样,本文将用代码演示示例,并将逐渐领导你实现一个残缺的人脸特色辨认示例。然而在开始之前,你须要启动一个新的 Python 我的项目并装置 3 个不同的库:
- opencv python
- dlib
如果像我一样应用 pipenv
,能够应用以下命令装置所有这些文件:
pipenv install opencv-python, dlib
如果你应用的是 Mac 和某些版本的 Linux,则在装置 dlib 时可能会遇到一些问题,如果在装置过程中遇到编译谬误,请确保查看应用的 CMake 库版本。在 Mac 中,确保你有可用的 CMake,并且能够应用正确的版本运行:
brew install cmake
对于其余操作系统,请在线查看以取得特定反对。
步骤 1:载入并显示图片
咱们将从小处着手并以代码为根底,直到有一个能够失常工作的示例为止。
通常,我喜爱应用绘图来渲染图像,然而因为咱们在稍后的文章中筹备了一些很酷的货色,因而咱们将做一些不同的事件,并且将创立一个窗口来展现咱们的工作后果。
让咱们一起看看代码吧!
import cv2
# read the image
img = cv2.imread("face.jpg")
# show the image
cv2.imshow(winname="Face", mat=img)
# Wait for a key press to exit
cv2.waitKey(delay=0)
# Close all windows
cv2.destroyAllWindows()
很简略,对吧?咱们只是用 imread 加载图像,而后通知 OpenCV 在 winname 中显示图像,这将关上窗口并给它一个题目。
之后,咱们须要暂停执行,因为当脚本进行时,窗口会被毁坏,所以咱们应用 cv2.waitKey 来放弃窗口,直到按下某个键,而后销毁窗口并退出脚本。
如果应用代码并在代码目录中增加了一个名为 face.jpg 的图像,你应该失去如下内容:
原始图像:
步骤 2:人脸识别
到目前为止,咱们还没有对图像做任何解决,只是把它出现在一个窗口中,十分无聊,然而当初咱们将开始编码好的内容,咱们将从辨认图像中哪里有一张脸开始。
为此,咱们将应用名为 get_frontial_face_detector() 的 Dlib 函数,十分直观。然而有一个正告,这个函数只实用于灰度图像,所以咱们必须首先应用 OpenCV。
get_frontial_face_detector()将返回一个检测器,该检测器是一个咱们能够用来检索人脸信息的函数。每个面都是一个对象,其中蕴含能够找到图像的点。
但咱们最好在代码上看看:
import cv2
import dlib
# Load the detector
detector = dlib.get_frontal_face_detector()
# read the image
img = cv2.imread("face.jpg")
# Convert image into grayscale
gray = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2GRAY)
# Use detector to find landmarks
faces = detector(gray)
for face in faces:
x1 = face.left() # left point
y1 = face.top() # top point
x2 = face.right() # right point
y2 = face.bottom() # bottom point
# Draw a rectangle
cv2.rectangle(img=img, pt1=(x1, y1), pt2=(x2, y2), color=(0, 255, 0), thickness=4)
# show the image
cv2.imshow(winname="Face", mat=img)
# Wait for a key press to exit
cv2.waitKey(delay=0)
# Close all windows
cv2.destroyAllWindows()
下面的代码将从图像中检索所有面部,并在每个面部上渲染一个矩形,从而产生如下图像:
到目前为止,咱们在发现人脸方面做得很好,然而咱们依然须要一些工作来提取所有特色(地标)。接下来让咱们开始吧。
步骤 3:辨认人脸特色
你喜爱魔术吗?到目前为止,DLib 的工作形式相当神奇,只需几行代码咱们就能够实现很多,而当初咱们遇到了一个全新的问题,它还会持续这么简略吗?
答复是必定的!原来 DLib 提供了一个名为 shape_predictor() 的函数,它将为咱们提供所有的魔法,然而须要一个事后训练的模型能力工作。
有几种模型能够与 shape_predictor 一起工作,我正在应用的模型能够在这里下载,也能够尝试其余模型。
让咱们看看新代码当初是什么样子
import cv2
import dlib
# Load the detector
detector = dlib.get_frontal_face_detector()
# Load the predictor
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# read the image
img = cv2.imread("face.jpg")
# Convert image into grayscale
gray = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2GRAY)
# Use detector to find landmarks
faces = detector(gray)
for face in faces:
x1 = face.left() # left point
y1 = face.top() # top point
x2 = face.right() # right point
y2 = face.bottom() # bottom point
# Look for the landmarks
landmarks = predictor(image=gray, box=face)
x = landmarks.part(27).x
y = landmarks.part(27).y
# Draw a circle
cv2.circle(img=img, center=(x, y), radius=5, color=(0, 255, 0), thickness=-1)
# show the image
cv2.imshow(winname="Face", mat=img)
# Wait for a key press to exit
cv2.waitKey(delay=0)
# Close all windows
cv2.destroyAllWindows()
像以前一样,咱们总是在同一个代码上构建代码,当初应用咱们的预测函数为每个人脸找到地标。当初我还在做一些奇怪的事件,比方 27 号在那里做什么?
landmarks = predictor(image=gray, box=face)
x = landmarks.part(27).x
y = landmarks.part(27).y
咱们的预测函数将返回一个蕴含所有 68 个点的对象,依据咱们之前看到的图片,如果你留神到的话,会发现点 27 正好在眼睛之间,所以如果所有的计算正确,你应该看到一个绿点在眼睛之间,如下图所示:
咱们曾经很靠近了,当初让咱们渲染所有的点,而不是只渲染一个:
import cv2
import numpy as np
import dlib
# Load the detector
detector = dlib.get_frontal_face_detector()
# Load the predictor
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# read the image
img = cv2.imread("face.jpg")
# Convert image into grayscale
gray = cv2.cvtColor(src=img, code=cv2.COLOR_BGR2GRAY)
# Use detector to find landmarks
faces = detector(gray)
for face in faces:
x1 = face.left() # left point
y1 = face.top() # top point
x2 = face.right() # right point
y2 = face.bottom() # bottom point
# Create landmark object
landmarks = predictor(image=gray, box=face)
# Loop through all the points
for n in range(0, 68):
x = landmarks.part(n).x
y = landmarks.part(n).y
# Draw a circle
cv2.circle(img=img, center=(x, y), radius=3, color=(0, 255, 0), thickness=-1)
# show the image
cv2.imshow(winname="Face", mat=img)
# Delay between every fram
cv2.waitKey(delay=0)
# Close all windows
cv2.destroyAllWindows()
然而如果你对所有的点都不感兴趣呢? 实际上,你能够调整你的范畴距离来取得下面术语表中指定的任何特色,就像我在这里做的那样:
太棒了,但咱们能做点更酷的事吗?
步骤 4:实时检测
是的,你没看错!这可能就是你想要的成果!下一步是连贯咱们的网络摄像头,从你的视频流中进行实时地标辨认。
你能够通过应用相机遍历视频帧或应用视频文件来对面部进行实时面部地标检测。
如果要应用本人的摄像机,请参考以下代码,如果应用的是视频文件,请确保将数字 0 更改为视频门路。
如果要完结窗口,请按键盘上的 ESC 键:
import cv2
import dlib
# Load the detector
detector = dlib.get_frontal_face_detector()
# Load the predictor
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
# read the image
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
# Convert image into grayscale
gray = cv2.cvtColor(src=frame, code=cv2.COLOR_BGR2GRAY)
# Use detector to find landmarks
faces = detector(gray)
for face in faces:
x1 = face.left() # left point
y1 = face.top() # top point
x2 = face.right() # right point
y2 = face.bottom() # bottom point
# Create landmark object
landmarks = predictor(image=gray, box=face)
# Loop through all the points
for n in range(0, 68):
x = landmarks.part(n).x
y = landmarks.part(n).y
# Draw a circle
cv2.circle(img=frame, center=(x, y), radius=3, color=(0, 255, 0), thickness=-1)
# show the image
cv2.imshow(winname="Face", mat=frame)
# Exit when escape is pressed
if cv2.waitKey(delay=1) == 27:
break
# When everything done, release the video capture and video write objects
cap.release()
# Close all windows
cv2.destroyAllWindows()
最初的后果是:
在弱光条件下,只管下面的图像中有一些谬误,但其后果也相当精确,如果照明成果好的话后果会更加精确。
论断
OpenCV 和 DLib 是两个性能十分弱小的库,它们简化了 ML 和计算机视觉的工作,明天咱们只是涉及了最根本的货色,还有很多货色须要从中学习。
非常感谢你的浏览!
原文链接:https://towardsdatascience.co…
欢送关注磐创 AI 博客站:
http://panchuang.net/
sklearn 机器学习中文官网文档:
http://sklearn123.com/
欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/