机器视觉——python实现网络摄像头(视频)人脸检测

from preprocess import FaceDetector
from preprocess import imutils
import argparse
import cv2

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-f", "--face", required = True,
help = "path to where the face cascade resides")
ap.add_argument("-v", "--video",
help = "path to the (optional) video file")
args = vars(ap.parse_args())
# construct the face detector
fd = FaceDetector(args["face"])

这里出现了一个新的包,imutils,这个包主要包含用于执行基本图像操作的便捷功能,例如调整大小。前面我们已经实现了imutils这个包了,如果没看的话,那么我们直接安装这个包也是可以的。执行pip install imutils就可以了,然后直接导入这个包即可(import imutils)。

我们同样需要一个haar级联分类器才能找到图像中的脸部。分类器被序列化为XML文件,可以由OpenCV加载。我们的face参数指向磁盘上的序列化XML级联分类器。

出于调试目的(或者系统没有网络摄像头),我们创建了一个可选的命令行参数--video,它指向磁盘上的视频文件。为了防止无法使用网络摄像头,使用视频文件测试和调试他的实时系统仍然是一件好事。在这种情况下,我们只需要提供我们的视频文件目录给video参数即可。

最后我们通过传递cascade classifier的路径实例化我们的FaceDetector。

# if a video path was not supplied, grab the reference
# to the gray

if not args.get("video"):
camera = cv2.VideoCapture(0)
else:
camera = cv2.VideoCapture(args["video"])

如果我们未提供视频路径。在这种情况下,OpenCV将尝试从笔记本电脑的内置(或USB)网络摄像头读取视频。否则,OpenCV将打开video参数指向的视频文件。

在任何一种情况下,都使用cv2.VideoCapture函数。提供整数值0指示OpenCV从网络摄像头设备读取,而提供字符串表示OpenCV应打开路径指向的视频。提供无效路径将导致空指针,如果没有有效的视频文件,我们显然无法进行任何面部检测。

假设抓取对视频的引用成功,我们将此指针存储在camera变量中。

# keep looping
while True:
# grab the current frame
(grabbed,frame) = camera.read()
# if we are viewing a video and we did not grab a
# frame, then we have reached the end of the video
if args.get("video") and not grabbed:
break
# resize the frame and convert it to grayscale
frame = imutils.resize(frame,width=300)
gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

下一步是开始循环视频中的所有帧 在最基本的层面上,视频只是放在一起的一系列图像,这意味着我们实际上可以一次读取这些帧。我们首先用while循环将保持循环遍历帧,直到满足以下两种情况之一:(1)视频已到达其结束且没有更多帧,或(2)用户过早地停止执行脚本。

在while循环里,我们首先通过调用相机的read()方法抓取视频中的下一帧。read方法返回两个值的元组:第一个是抓取的,用布尔值表示读取帧是否成功的true或false,第二个就是抓取的帧本身。

如果我们正在从文件中读取视频,但是并没有抓取到帧,则说明视频结束,这个时候应该用break退出循环。

否则,我们对帧进行一些预处理。首先就是调整帧的大小,使其宽度为300像素,以便更快地实时进行人脸检测。然后将帧转换为灰度。

 # detect faces in the image and then clone the frame
# so that we can draw on it
faceRects = fd.detect(gray,scaleFactor=1.1,minNeighbors=5,
minSize=(30,30))
frameClone = frame.copy()
# loop over the face bounding boxes and draw them
for (fX,fY,fW,fH) in faceRects:
cv2.rectangle(frameClone,(fX,fY),(fX + fW,fY + fH),(0,255,0),2)
# show our detected faces
cv2.imshow("Face",frameClone)
# if the 'q' key is pressed, stop the loop
if cv2.waitKey(1) & 0xFF == ord("q"):
break
# cleanup the camera and close any open windows
camera.release()
cv2.destroyAllWindows()

我们首先传递了灰度帧并应用了FaceDetector的detect方法。

但是为了在我们的图像上绘制一个边界框,我们决定首先创建一个框架的克隆,以防万一我们需要原始框架进行进一步的预处理。帧的克隆存储在frameClone中。

然后我们遍历图像中面部的边界框,并使用cv2.rectangle函数绘制它们。然后显示我们的结果。

当然,用户可能希望停止执行脚本。我们不用强制输入ctrl+c,而是检查用户是否在键盘上按了q键。

最后,我们release了对相机的引用,并且关闭了由OpenCV创建的任何打开的窗口。

执行脚本文件

提供video视频文件:

python cam.py --face cascades\haarcascade_frontalface_default.xml --video video\myvideo.mp4

不提供video文件

python cam.py --face cascades\haarcascade_frontalface_default.xml

执行结果:

机器视觉——python实现网络摄像头(视频)人脸检测

机器视觉——python实现网络摄像头(视频)人脸检测

博客地址(有完整代码):https://0leo0.github.io/2018/case_study_02.html

关注不迷路哦


分享到:


相關文章: