使用Python和OpenCV进行面部识别

面部识别技术近年来取得了飞速的进步,被广泛应用于各种领域。以下是一些应用实例:

  • 帮助盲人导航
  • 辅助法医调查
  • 预防犯罪
  • 智能广告
  • 社交媒体上的人员识别
  • 寻找失踪人员
  • 保护学校免受威胁
  • 在ATM机上验证身份
  • 跟踪教堂的出勤率

本教程将教如何轻松创建自己的视频面部识别应用程序。将使用Python中的OpenCV库。在几分钟内,将获得开始面部识别所需的一切。将直接进入两个重要部分,并提供一个链接到详细解释将使用的算法理论的文章。

代码(逐步)

OpenCV算法使用Haar级联过滤器进行检测。它包含了代码所需的所有参数,以识别面部或其部分。可以在文章末尾提供的链接中阅读有关面部检测理论的更多信息。首先,复制以下级联并将其作为XML粘贴到与脚本相同的文件夹中:

<文件夹与脚本和Haar级联XML文件> 面部 眼睛

让开始编码,导入库和XML文件。

import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

现在,将创建一个函数,该函数将访问相机并寻找面部。在找到面部后,它将在面部内寻找眼睛。这将节省大量处理时间,避免在整个帧中寻找眼睛。将在下面展示完整的函数,并提供每个步骤的解释。

def detect(gray, frame) # 大多数时候,处理图像和机器学习时,使用灰度图像可以减少数据量并提高代码效率。这里将这样做。 # 这个函数将读取两个参数,gray和frame,其中gray是来自相机的最后一个帧的灰度版本, # frame是来自相机的最后一个帧的原始版本。 faces = face_cascade.detectMultiScale(gray, 1.3, 5) # MultiScale检测输入图像中不同大小的物体,并返回定位在面部上的矩形。第一个参数是图像, # 第二个是scalefactor(每次图像缩放时图像大小减少的量),第三个是minNeighbors(每个矩形应 # 该有多少邻居)。1.3和5的值是基于实验选择的最佳值。 for (x, y, w, h) in faces: # 将循环遍历每个矩形(每个检测到的面部)及其由上述函数生成的坐标。 cv2.rectangle(frame, (x,y), (x+w, y+h), (255, 0, 0), 2) # 在相机捕获的原始图像中绘制矩形(最后一帧)。(255,0,0)是RGB颜色中的帧颜色。 # 最后一个参数(2)是矩形的厚度。 # x是水平初始位置,w是宽度,y是垂直初始位置,h是高度。 roi_gray = gray[y:y+h, x:x+w] # 这里将roi_gray设置为兴趣区域。那是将寻找眼睛的地方。 roi_color = frame[y:y+h, x:x+w] # 在原始帧中获取兴趣区域(彩色的,不是黑白的)。 # 现在,应用相同的概念来寻找眼睛。不同的是,不会在整个图像中寻找。 # 将使用兴趣区域(roi_gray和roi_color),然后在frame中绘制眼睛的矩形。 eyes = eye_cascade.detectMultiScale(roi_gray, 1.1, 18) for (ex, ey, ew, eh) in eyes: cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2) return frame

现在将访问相机并使用刚刚创建的函数。代码将不断从相机获取快照,并应用detect()函数来检测面部和眼睛并绘制矩形。将向展示整个代码块,然后再次逐步解释它。

video_capture = cv2.VideoCapture(0) while True: _, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) canvas = detect(gray, frame) cv2.imshow('Video', canvas) if cv2.waitKey(1) & 0xFF == ord('q') : break video_capture = cv2.VideoCapture(0) # 这里正在访问相机。当参数为0时,正在访问计算机的内部相机。 # 当参数为1时,正在访问连接到计算机的外部相机。 while True: # 只要相机打开(直到使用将定义的键关闭它),就会继续运行detect函数。 _, frame = video_capture.read() # read()函数将返回2个对象,但只对最新的一个感兴趣,即相机的最后一帧。 # 因此,忽略了第一个对象_,并命名第二个对象为frame,将在稍后使用它来 # 喂养detect函数。 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 刚刚从上面的函数中读取了帧,并将其转换为灰度。将其命名为gray, # 也将使用它来喂养detect函数。 canvas = detect(gray, frame) # Canvas将是工作用的图像。 cv2.imshow('Video', canvas) # imshow()在窗口中显示图像。因此,将看到相机('Video')并应用canvas(detect()函数) # 在新窗口中。 if cv2.waiKey(1) & 0xFF == ord('q') : break # 这段代码将在按下键盘上的q时停止程序。

现在,只需要在停止程序时关闭相机并关闭窗口。使用以下语法:

video_capture.release() # 关闭相机 cv2.destroyAllWindows() # 关闭窗口

就是这样。已经准备好检测面部和眼睛了。检查下面的完整代码。

import cv2 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') def detect(gray, frame) : faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2) roi_gray = gray[y:y+h, x:x+w] roi_color = frame[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray, 1.1, 18) for (ex, ey, ew, eh) in eyes: cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2) return frame video_capture = cv2.VideoCapture(0) while True: _, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) canvas = detect(gray, frame) cv2.imshow('Video', canvas) if cv2.waitKey(1) & 0xFF == ord('q') : break video_capture.release() # 关闭相机 cv2.destroyAllWindows() # 关闭窗口

现在一起运行所有内容,一个新窗口将弹出。

额外部分

幸福检测!!让在程序中添加几行代码,以便可以检测某人何时微笑。首先,复制Haar级联用于微笑,并如下读取XML文件(在读取面部和眼睛的XML文件后,即在代码的开头写入):

smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml')

当检测到面部时,得到要寻找眼睛的兴趣区域,对吧?在寻找眼睛之后,让也寻找微笑。微笑的代码将放在detect()函数内的return frame之前。参数遵循为面部和眼睛看到的相同概念,它们是基于实验选择的最佳值。

smiles = smile_cascade.detectMultiScale(roi_gray, 1.1, 22) for (sx, sy, sw, sh) in smiles: cv2.rectangle(roi_color, (sx, sy), (sx+sw, sy+sh), (0, 0, 255), 2) # 库 import cv2 # Haar级联 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml') smile_cascade = cv2.CascadeClassifier('haarcascade_smile.xml') # 检测函数 def detect(gray, frame) : faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 2) roi_gray = gray[y:y+h, x:x+w] roi_color = frame[y:y+h, x:x+w] eyes = eye_cascade.detectMultiScale(roi_gray, 1.1, 18) for (ex, ey, ew, eh) in eyes: cv2.rectangle(roi_color, (ex, ey), (ex+ew, ey+eh), (0, 255, 0), 2) smiles = smile_cascade.detectMultiScale(roi_gray, 1.1, 22) for (sx, sy, sw, sh) in smiles: cv2.rectangle(roi_color, (sx, sy), (sx+sw, sy+sh), (0, 0, 255), 2) return frame # 访问相机并应用detect()函数 video_capture = cv2.VideoCapture(0) while True: _, frame = video_capture.read() gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) canvas = detect(gray, frame) cv2.imshow('Video', canvas) if cv2.waitKey(1) & 0xFF == ord('q') : break # 关闭一切 video_capture.release() # 关闭相机 cv2.destroyAllWindows() # 关闭窗口
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485