Python中怎么检测人脸特征,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
与往常一样,本文将用代码演示示例,并将逐步指导你实现一个完整的人脸特征识别示例。但是在开始之前,你需要启动一个新的Python项目并安装3个不同的库:
opencv python
dlib
如果像我一样使用pipenv
,可以使用以下命令安装所有这些文件:
pipenv install opencv-python, dlib
如果你使用的是Mac和某些版本的Linux,则在安装dlib时可能会遇到一些问题,如果在安装过程中遇到编译错误,请确保检查使用的CMake库版本。在Mac中,确保你有可用的CMake,并且可以使用正确的版本运行:
brew install cmake
对于其他操作系统,请在线检查以获得特定支持。
我们将从小处着手并以代码为基础,直到有一个可以正常工作的示例为止。
通常,我喜欢使用绘图来渲染图像,但是由于我们在稍后的文章中准备了一些很酷的东西,因此我们将做一些不同的事情,并且将创建一个窗口来展示我们的工作结果。
让我们一起看看代码吧!
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的图像,你应该得到如下内容:
原始图像:
到目前为止,我们还没有对图像做任何处理,只是把它呈现在一个窗口中,非常无聊,但是现在我们将开始编码好的内容,我们将从识别图像中哪里有一张脸开始。
为此,我们将使用名为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()
上面的代码将从图像中检索所有面部,并在每个面部上渲染一个矩形,从而产生如下图像:
到目前为止,我们在发现人脸方面做得很好,但是我们仍然需要一些工作来提取所有特征(地标)。接下来让我们开始吧。
你喜欢魔术吗?到目前为止,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()
但是如果你对所有的点都不感兴趣呢?实际上,你可以调整你的范围间隔来获得上面术语表中指定的任何特征,就像我在这里做的那样:
太棒了,但我们能做点更酷的事吗?
是的,你没看错!这可能就是你想要的效果!下一步是连接我们的网络摄像头,从你的视频流中进行实时地标识别。
你可以通过使用相机遍历视频帧或使用视频文件来对面部进行实时面部地标检测。
如果要使用自己的摄像机,请参考以下代码,如果使用的是视频文件,请确保将数字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()
看完上述内容,你们掌握Python中怎么检测人脸特征的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。