ros2人脸检测

第一步:

首先在工作空间/src下创建数据结构目录service_interfaces

ros2 pkg create service_interfaces --build-type ament_cmake

然后再创建一个srv目录

在里面创建FaceDetect.srv(注意,首字母要大写

sensor_msgs/Image photo
---
uint16 number
float32 use_time

int32[] top
int32[] right
int32[] bottom
int32[] left

CmakeList.txt

cmake_minimum_required(VERSION 3.8)
project(service_interfaces)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
# 添加依赖
find_package(sensor_msgs REQUIRED)  # 确保这个包在这里被找到
# 声明srv文件所属的工程名字, 文件位置, 依赖DEPENDENCIES
find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
  "srv/FaceDetect.srv"
  DEPENDENCIES 
  sensor_msgs    
 )



if(BUILD_TESTING)
  find_package(ament_lint_auto REQUIRED)
  # the following line skips the linter which checks for copyrights
  # comment the line when a copyright and license is added to all source files
  set(ament_cmake_copyright_FOUND TRUE)
  # the following line skips cpplint (only works in a git repo)
  # comment the line when this package is in a git repo and when
  # a copyright and license is added to all source files
  set(ament_cmake_cpplint_FOUND TRUE)
  ament_lint_auto_find_test_dependencies()
endif()

ament_package()

package.xml

加上依赖

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>service_interfaces</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="root@todo.todo">root</maintainer>
  <license>TODO: License declaration</license>

  <buildtool_depend>ament_cmake</buildtool_depend>
  <depend>sensor_msgs</depend>

  <build_depend>rosidl_default_generators</build_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_group>rosidl_interface_packages</member_of_group>
  <test_depend>ament_lint_auto</test_depend>
  <test_depend>ament_lint_common</test_depend>

  <export>
    <build_type>ament_cmake</build_type>
  </export>
</package>

第二步:

要准备好人脸识别的库,不懂的可以看我的另一篇文章《Ubuntu如何使用pip》

要安装好face_recognition的库

cpp 复制代码
pip install face_recognition

安装成功后即可

第三步

在工作空间/src下创建功能包

ros2 pkg create hj_service --build-type ament_cmake --dependencies rclcpp service_interfaces

接着创建face_detect_client.py

在这个代码里面,你需要准备好一张里面有人脸的图片

cpp 复制代码
import rclpy
from rclpy.node import Node
from service_interfaces.srv import FaceDetect
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2
import sys

class FaceDetectClientNode(Node):
    def __init__(self):
        super().__init__('face_detect_client_node')
        self.client = self.create_client(FaceDetect, 'face_detect_service')
        while not self.client.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('Service not available, waiting again...')
        self.bridge = CvBridge()
        self.cv_image = None  # 初始化cv_image为类属性

    def send_request(self, image_path):
        try:
            # 读取图像文件
            self.cv_image = cv2.imread(image_path)  # 保存cv_image为类属性
            if self.cv_image is None:
                self.get_logger().info('Failed to read image')
                return

            # 将OpenCV图像转换为ROS图像消息
            msg = self.bridge.cv2_to_imgmsg(self.cv_image, encoding="bgr8")

            # 构建服务请求
            request = FaceDetect.Request()
            request.photo = msg

            # 调用服务
            self.future = self.client.call_async(request)

        except CvBridgeError as e:
            self.get_logger().info('CvBridge Error: {0}'.format(e))

    def get_response(self):
        while rclpy.ok():
            rclpy.spin_once(self)
            if self.future.done():
                try:
                    response = self.future.result()
                except Exception as e:
                    self.get_logger().info('Service call failed %r' % (e,))
                else:
                    self.get_logger().info('Service response: use_time: %f, number: %d' % (response.use_time, response.number))
                    for i in range(response.number):
                        self.get_logger().info('Face %d: top: %d, right: %d, bottom: %d, left: %d' %
                                               (i, response.top[i], response.right[i], response.bottom[i], response.left[i]))
                        
                    # 绘制人脸边框
                    for i in range(response.number):
                        top = response.top[i]
                        right = response.right[i]
                        bottom = response.bottom[i]
                        left = response.left[i]
                        cv2.rectangle(self.cv_image, (left, top), (right, bottom), (0, 255, 0), 2)
                    
                    # 显示图像
                    cv2.imshow('Detected Faces', self.cv_image)
                    cv2.waitKey(0)  # 等待按键
                    cv2.destroyAllWindows()  # 关闭所有窗口
                break

def main(args=None):
    rclpy.init(args=args)
    node = FaceDetectClientNode()
    # 替换'image.jpg'为你的图像文件路径
    node.send_request('/home/phj/Downloads/test.jpeg')
    node.get_response()
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

face_detect_server.py

cpp 复制代码
import rclpy
from rclpy.node import Node
from service_interfaces.srv import FaceDetect
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2
import face_recognition
import time

class FaceDetectServerNode(Node):
    def __init__(self, node_name):
        super().__init__(node_name)
        self.service = self.create_service(FaceDetect, 'face_detect_service', self.face_detect_callback)
        self.bridge = CvBridge()
        self.get_logger().info('Service created.')

    def face_detect_callback(self, request, response):
        if request.photo.data:
            try:
                cv_image = self.bridge.imgmsg_to_cv2(request.photo, "bgr8")
            except CvBridgeError as e:
                self.get_logger().info('CvBridge Error: %s' % e)
                return
        else:
            self.get_logger().info("No image data received")
            return

        start = time.time()
        face_locations = face_recognition.face_locations(cv_image, model="hog")
        response.use_time = time.time() - start
        response.number = len(face_locations)

        # Initialize lists in the response
        response.top = []
        response.right = []
        response.bottom = []
        response.left = []

        for (top, right, bottom, left) in face_locations:
            response.top.append(top)
            response.right.append(right)
            response.bottom.append(bottom)
            response.left.append(left)

        return response

def main(args=None):
    rclpy.init(args=args)
    node = FaceDetectServerNode('face_detect_server_node')
    rclpy.spin(node)
    node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()

package.xml

cpp 复制代码
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>hj_service</name>
  <version>0.0.0</version>
  <description>TODO: Package description</description>
  <maintainer email="root@todo.todo">root</maintainer>
  <license>TODO: License declaration</license>

  <depend>rclpy</depend>
  <depend>service_interfaces</depend>
  <depend>sensor_msgs</depend>
  <test_depend>ament_copyright</test_depend>
  <test_depend>ament_flake8</test_depend>
  <test_depend>ament_pep257</test_depend>
  <test_depend>python3-pytest</test_depend>

  <export>
    <build_type>ament_python</build_type>
  </export>
</package>

setup.py

cpp 复制代码
from setuptools import find_packages, setup

package_name = 'hj_service'

setup(
    name=package_name,
    version='0.0.0',
    packages=find_packages(exclude=['test']),
    data_files=[
        ('share/ament_index/resource_index/packages',
            ['resource/' + package_name]),
        ('share/' + package_name, ['package.xml']),
    ],
    install_requires=['setuptools'],
    zip_safe=True,
    maintainer='root',
    maintainer_email='root@todo.todo',
    description='TODO: Package description',
    license='TODO: License declaration',
    tests_require=['pytest'],
    entry_points={
        'console_scripts': [
            'service = hj_service.service_member_function:main',
            'client = hj_service.client_member_function:main',
            'param_sample = hj_service.param:main',
            "face_detect_server_node = hj_service.face_detect_server:main",
            "face_detect_client_node = hj_service.face_detect_client:main"
        ],
    },
)

第四步:

打开一个终端

cpp 复制代码
ros2 run hj_service face_detect_server_node

打开另一个终端

cpp 复制代码
ros2 run hj_service face_detect_client_node

成功!

相关推荐
久未8 天前
ROS2创建 base 包用于其他模块的参数配置和头文件依赖
ros2·软件工程项目
G果11 天前
四轮转向键盘控制改进版 ros2(python)
开发语言·python·ubuntu·ros2·gazebo·四轮转向·阿克曼
coco_1998_215 天前
ROS2-参数服务器
ros2
Learning改变世界23 天前
pip/conda install bugs汇总
ros2
Mr.Winter`24 天前
轨迹优化 | 基于Savitzky-Golay滤波的无约束路径平滑(附ROS C++/Python仿真)
人工智能·算法·机器人·自动驾驶·ros·ros2·数值优化
huanggang9821 个月前
在Ubuntu22.04上使用Qt Creator开发ROS2项目
qt·ros2
Mr.Winter`1 个月前
路径规划 | ROS中多个路径规划算法可视化与性能对比分析
人工智能·算法·机器人·自动驾驶·ros·ros2·路径规划
无处在1 个月前
Ubuntu 22.04系统启动时自动运行ROS2节点
linux·ubuntu·ros2
lucust2 个月前
navigation2-humble依赖
c++·ros2·navigation