这是一个基于 ROS2 Python Service 的人脸检测项目,使用 face_recognition 和 OpenCV 完成人脸位置检测,并通过自定义服务接口返回检测结果。
项目主要包含以下内容:
- 一个独立的人脸检测学习脚本
learn_face_detect.py - 一个服务端节点
face_detect_node.py - 一个客户端节点
face_detect_client_node.py
该项目适合用于学习以下内容:
- ROS2 Python 节点开发
- ROS2 Service 通信机制
- OpenCV 图像读取与显示
cv_bridge在 ROS 图像消息与 OpenCV 图像之间的转换face_recognition的基础使用
本项目实现了一个简单的人脸检测流程:
- 客户端读取本地图片
- 客户端将图片转换为 ROS 图像消息并发送给服务端
- 服务端接收图片后进行人脸检测
- 服务端将检测到的人脸数量、检测耗时、以及每张人脸的位置坐标返回给客户端
- 客户端根据返回结果在图像上绘制矩形框,并显示检测结果
CHAPT4/
├── demo_python_service/
│ ├── demo_python_service/
│ │ ├── face_detect_client_node.py
│ │ ├── face_detect_node.py
│ │ └── learn_face_detect.py
│ ├── resource/
│ │ ├── default.jpg
│ │ └── test1.jpg
│ ├── package.xml
│ ├── setup.py
│ └── ...
├── chapt4_interfaces/
│ ├── srv/
│ │ └── FaceDetector.srv
│ ├── package.xml
│ ├── CMakeLists.txt
│ └── ...
└── README.md这是一个最基础的人脸检测学习脚本,用来直接读取图片并检测人脸位置,不涉及 ROS2 通信。
- 从功能包的
resource/default.jpg读取图片 - 使用
face_recognition.face_locations()检测人脸 - 使用 OpenCV 在图像上绘制人脸框
- 弹窗显示检测结果
这个脚本适合用来先验证:
face_recognition是否安装成功- OpenCV 是否能正常读取和显示图像
- 人脸检测逻辑本身是否正确
这是服务端节点,节点名为:
face_detect_node-
创建名为
face_detect的服务 -
接收客户端发送的图像消息
-
将 ROS 图像消息转换为 OpenCV 图像
-
使用
face_recognition完成人脸检测 -
返回检测结果,包括:
-
人脸数量
number -
检测耗时
use_time -
每张人脸的位置:
toprightbottomleft
-
如果客户端请求中没有携带图像数据,则服务端会自动使用默认图片:
resource/default.jpg然后进行人脸检测。
当前服务端使用如下参数:
self.number_of_times_to_upsample = 1
self.model = "hog"说明:
number_of_times_to_upsample=1:对图像放大一次后再检测,有助于识别较小的人脸,但会增加耗时model="hog":使用 HOG 模型进行检测,速度较快,适合 CPU 环境
这是客户端节点,节点名为:
face_detect_client- 创建到
face_detect服务的客户端 - 读取本地测试图片
resource/test1.jpg - 将 OpenCV 图像转换为 ROS 图像消息
- 异步调用服务
- 在收到响应后输出检测结果
- 根据返回的人脸坐标在原图中绘制矩形框
- 显示最终检测结果
客户端会输出类似信息:
Number of faces detected: 1, Time taken: 0.15 seconds随后弹出检测结果窗口。
客户端使用的是:
future = self.client.call_async(request)
future.add_done_callback(result_callback)这是一种异步服务调用方式,能够避免直接阻塞在请求阶段,更符合 ROS2 的事件驱动机制。
项目使用了自定义服务:
chapt4_interfaces/srv/FaceDetector.srv根据你的代码逻辑,这个服务大概率包含以下两部分内容:
请求部分:
- 一张图像
image
响应部分:
number:检测到的人脸数量use_time:检测耗时top[]right[]bottom[]left[]
这些数组分别存储每张人脸框的位置坐标。
整个系统的数据流如下:
本地图片 -> 客户端读取 -> 转换为 ROS 图像消息 -> 调用 face_detect 服务
-> 服务端接收请求 -> 转换为 OpenCV 图像 -> face_recognition 检测人脸
-> 返回人脸数量、耗时、坐标 -> 客户端接收响应 -> OpenCV 绘制方框 -> 显示图像
运行本项目通常需要以下依赖:
rclpycv_bridgeament_index_python
opencv-pythonface_recognition
- 自定义接口包
chapt4_interfaces
在 ROS2 工作空间下编译项目。
cd ~/your_ros2_wscolcon build如果只想编译相关包,也可以使用:
colcon build --packages-select chapt4_interfaces demo_python_servicesource install/setup.bash打开一个终端:
source install/setup.bash
ros2 run demo_python_service face_detect_node再打开一个终端:
source install/setup.bash
ros2 run demo_python_service face_detect_client_node如果你想先不跑 ROS2 通信,只测试人脸检测功能,可以运行:
source install/setup.bash
ros2 run demo_python_service learn_face_detect这个脚本会直接读取默认图片并显示检测结果。
服务端负责真正的人脸检测任务,主要优点:
- 将检测逻辑集中在服务端,结构清晰
- 客户端只负责发送请求和显示结果
- 便于以后扩展成其他客户端调用同一个检测服务
客户端主要负责:
- 准备输入图像
- 请求服务
- 接收结果
- 可视化检测结果
这样实现了输入、处理、输出三个环节的分离。
运行成功后,客户端会:
- 在终端输出检测到的人脸数量和耗时
- 弹出一个 OpenCV 窗口,显示带有人脸框的图片
例如:
[INFO] [face_detect_client]: Number of faces detected: 1, Time taken: 0.12 seconds在客户端的 show_response() 中:
cv2.waitKey(0)这会让程序一直等待键盘输入,窗口不关闭时节点也不会继续退出。
虽然请求发送使用了异步方式,但图像显示部分依然可能因为 OpenCV 窗口阻塞而影响程序退出。
当前代码中图片路径通过:
get_package_share_directory('demo_python_service')获取,因此运行前需要确保图片资源已经正确安装到功能包中。
如果系统中没有正确安装 dlib 或 face_recognition,程序将无法正常运行。
这个项目目前已经完成了基础的人脸检测服务通信,后续可以继续扩展:
当前是读取本地图片,后续可以改为:
- 摄像头采集
- 视频流检测
- ROS2 图像话题订阅
目前使用的是 Service,更适合“请求-响应”模式。 如果想做连续检测,可以改为 Topic 订阅/发布模式。
当前使用的是:
model="hog"后续可以尝试:
cnn模型(更高精度,但更慢)- GPU 加速
客户端在显示结果后,还可以把绘制完的人脸框图片保存到本地。
例如:
- 图片读取失败
- 服务不可用
- 返回结果为空
- OpenCV 窗口异常关闭
通过这个项目,可以练习并掌握以下知识点:
- ROS2 Python 节点编写
- ROS2 Service 服务端与客户端通信
- 自定义
.srv接口设计 - OpenCV 图像处理
cv_bridge图像格式转换face_recognition人脸检测基础流程- 异步调用与回调处理方式
这是一个基于 ROS2 的基础人脸检测项目。 项目通过 客户端发送图片 + 服务端检测 + 客户端显示结果 的方式,实现了完整的人脸检测服务流程。
它适合作为以下方向的入门项目:
- ROS2 服务通信练习
- Python 机器人视觉项目
- OpenCV 与 ROS2 结合
- 智能感知类课程作业或实验项目