Logo
Section 1 / 6

人脸检测

让我们学习如何在数字图像中定位人脸。

导入

人脸检测

让我们学习如何在数字图像中定位人脸。

简介

人脸检测是一种计算机技术,能够实现以下功能:

  • 在数字图像中定位人脸。
  • 识别特定人脸的关键面部特征,并获取它们的坐标位置。
  • 分析并勾勒出检测到的人脸轮廓。

通常认为,人脸检测是迈向其他与人脸相关技术(如人脸识别或人脸特征码生成)的第一步。

人脸检测的重要应用

越来越多的应用场景正在利用这项技术,包括但不限于:

  • 人群监控:监控拥挤的公共或私人区域,或统计进入特定区域的人数。
  • 摄影:在数码相机中自动对焦并优化曝光参数。
  • 考勤管理:结合生物特征检测技术,实现人员考勤管理及门禁控制。
  • 市场营销:分析顾客行为或触发精准广告投放——例如,当检测到某一性别的面部时,自动展示对应的广告内容。
  • 动作捕捉:将某个人的面部动作存储到数字数据库中,并基于这些数据为电影、游戏或虚拟形象生成生动的计算机动画。
  • 隐私保护增强:通过对画面中检测到的人脸进行模糊化或匿名化处理,提升视频共享的安全性与隐私性。

目标

在本课程中,我们将学习如何使用前沿的 MediaPipe 库,在 Python 编程语言中实现一个人脸检测系统。

...

依赖库

需要安装以下 Python 外部库:

人脸检测所需的外部库

库名版本
MediaPipe0.8.9
opencv-python4.4.0.46
imutils0.5.3
filetype1.0.7

开始编码

我们将构建该工具的核心函数 detect_faces_mp,用于在数字图像中定位并提取出人脸区域。

在以下代码片段中,执行了如下步骤:

  • 第 7 行:初始化 MediaPipe 库,并使用预设参数加载人脸检测模型。

  • 第 10 行:加载并读取指定的输入图像。

  • 第 13–14 行:保留原始图像的一份副本,并按预设尺寸调整大小,用于后续处理。

  • 第 17 行:将图像从蓝绿红(BGR)格式转换为红绿蓝(RGB)格式,以符合 MediaPipe 库的要求。需要注意的是,OpenCV 默认以 BGR 格式读取图像。

  • 第 20 行:使用 MediaPipe 的人脸检测子模块处理图像。

  • 第 26–27 行:输出一条消息,显示检测到的人脸数量。

  • 第 30 行:遍历所有检测到的人脸。

  • 第 33–34 行:为每个检测到的人脸输出一条信息,包含我们为其分配的编号以及 MediaPipe 生成的置信度得分。

  • 第 37–42 行:通过确定边界框来定位检测到的人脸。默认情况下,MediaPipe 返回的是归一化的三维检测数据,每个关键点包含 [x, y, z] 三个属性。为了将归一化数据转换为二维像素坐标,需将 x 值乘以图像宽度,y 值乘以图像高度。

  • 第 49–54 行:在边界框上绘制矩形,作为感兴趣区域(ROI),并将其裁剪出来。

  • 第 57–60 行:返回裁剪后的感兴趣区域。

  • 第 72 行:关闭对象并释放资源。

完整的 detect_faces_mp 函数代码如下所示:

1def detect_faces_mp(input_path:str,display_output:bool = False): 2 """ 3 检测图像中出现的人脸 4 """ 5 6 # 初始化 MediaPipe 人脸检测子模块 7 mpFaceDetection = initialize_mediapipe() 8 9 # 读取输入图像 10 img = cv2.imread(input_path) 11 12 # 保留原始图像副本 13 frame = img.copy() 14 frame = imutils.resize(frame, width=FRAME_WIDTH, height=FRAME_HEIGHT) 15 16 # 将图像从 BGR 转换为 RGB 格式 17 rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 18 19 # 使用 RGB 图像进行人脸检测 20 faces = mpFaceDetection.process(rgb_frame) 21 22 output = [] 23 output_info = [] 24 25 # 消息分类:info, success, warning, danger 26 output_msg = {'msg':"{} 张人脸被检测到。".format(len(faces.detections)),'category':"info"} 27 output_info.append(output_msg) 28 29 # 遍历检测到的每张人脸 30 for idx, face_detected in enumerate(faces.detections): 31 32 output_item = None 33 label = f"人脸 ID = {(idx+1)} - 检测置信度 {int(face_detected.score[0]*100)}%" 34 print(label) 35 36 # 获取相对边界框 37 relativeBoundingBox = face_detected.location_data.relative_bounding_box 38 frameHeight,frameWidth,frameChannels = frame.shape 39 faceBoundingBox = int(relativeBoundingBox.xmin*frameWidth) \ 40 ,int(relativeBoundingBox.ymin*frameHeight) \ 41 ,int(relativeBoundingBox.width*frameWidth) \ 42 ,int(relativeBoundingBox.height*frameHeight) 43 44 # 重新复制原始图像并调整尺寸 45 frame = img.copy() 46 frame = imutils.resize(frame, width=FRAME_WIDTH, height=FRAME_HEIGHT) 47 48 # 在边界框周围绘制矩形 49 cv2.rectangle(frame, faceBoundingBox, (0,255,0),3) 50 51 x,y,w,h = faceBoundingBox 52 53 # 彩色模式下的感兴趣区域(人脸区域) 54 roi_face_color = frame[y:y+h,x:x+w] 55 56 # 保存裁剪后的人脸图像 57 output_filepath = os.path.join(config.PROCESSED_PATH, str(uuid.uuid4().hex) + os.path.splitext(input_path)[1]) 58 cv2.imwrite(output_filepath, roi_face_color) 59 output_item = {'id':idx, 'folder': config.PROCESSED_FOLDER, 'name':os.path.basename(output_filepath) , 'msg':label } 60 output.append(output_item) 61 62 if display_output: 63 # 在屏幕上显示裁剪结果 64 cv2.imshow(label,roi_face_color) 65 # 保持窗口显示,直到用户按键 66 cv2.waitKey(0) 67 68 if display_output: 69 # 清理窗口 70 cv2.destroyAllWindows() 71 72 mpFaceDetection.close() 73 74 return output_info , output

测试场景

让我们尝试在一个数字图像中定位人脸。运行程序后,请按照以下步骤操作:

  • 从已上传的图像中选择一张进行测试。值得注意的是,也可以随时上传自定义图像进行处理。
  • 选择并运行人脸检测流程。

No configuration found for ID: 8f94db6af6571ada11d0823ab042bf8ee053b34a26c382afcb5eeb9e6be651a9

为了加深理解,我们可以尝试修改上述代码,设计自己的测试用例!

结论

人脸检测在人脸分析、跟踪和识别等领域中起着至关重要的作用。MediaPipe 提供的人脸检测方案具有超快的速度、高性能和高精度,能够有效从数字图像中提取出人脸区域。

简介

使用Dlib进行人脸关键点检测