自学内容网 自学内容网

感知笔记4:YOLO 3D 物体定位

如何在 ROS 中使用 YOLO

  • 如何在 2D 中检测人和大象
  • 如何在 3D 中检测人和大象

有许多可用的深度学习库。您可能听说过:Keras、TensorFlow 和 Darknet。

在这里我们将使用 Darknet,因为它实现了 YOLOv3,这是一个对象检测模型。它非常快,尤其是在支持 CUDA 的系统中使用它时。它旨在进行实时检测,这对于机器人技术来说非常重要。

3.4   2D YOLO 检测

我们将首先使用适用于 ROS 的 YOLO 版本创建我们自己的启动:

roscd my_object_recognition_pkg
touch launch/yolo_v2_tiny.launch
 yolo_v2_tiny.launch 
<?xml version="1.0" encoding="utf-8"?>

<launch>
  
  <!-- Use YOLOv3 -->
  <arg name="network_param_file"         default="$(find darknet_ros)/config/yolov2-tiny.yaml"/>
  <!-- 设置输入 RGB ROS 相机主题。这是最重要的参数,也是您需要更改的唯一参数。-->
  <arg name="image" default="/camera/rgb/image_raw" />


  <!-- Include main launch file -->
  <include file="$(find darknet_ros)/launch/darknet_ros.launch">
    <arg name="network_param_file"    value="$(arg network_param_file)"/>
    <arg name="image" value="$(arg image)" />
  </include>

</launch>

YOLO 有不同的版本:v2、v3 和 v4。每个版本都适用于不同的 OpenCV 库,理论上每个新版本都运行得更好。

在本单元中,我们将使用 v2 Tiny(更快的版本),因为它对系统的影响较小且性能更快。

如果您想要原始源代码,请查看以下 Git:

YOLO Darknet ROS

Darknet ROS

Original Source Git

启动并查看输出:

 

# Set variables only for this course, locally you wont need it
QT_X11_NO_MITSHM=1
echo $QT_X11_NO_MITSHM
# Start yolo V2-tiny
roslaunch my_object_recognition_pkg yolo_v2_tiny.launch

注意:首次启动可能会导致 GTK 错误。不要惊慌。重新启动它应该可以正常工作。

移动 PR2 机器人,看看它如何检测不同的物体。

roslaunch pr2_tc_teleop keyboard_teleop.launch

3.5 使用 YOLO 进行 3D 物体检测和定位

这个由 Francisco Martin 创建的 Darknet_ROS_3D 结合使用 darknet_ros 和点云数据将检测结果与 3D 空间进行匹配,从而大致确定检测到的物体在 3D 空间中的位置。

这对于抓取、自主导航和许多其他应用至关重要。

roscd my_object_recognition_pkg
touch config/darknet_3d.yaml
touch launch/darknet_ros_3d.launch
darknet_ros_3d.launch
<launch>

  <!-- Config camera image topic  -->
  <arg name="camera_rgb_topic" default="/camera/rgb/image_raw" />

  <!-- Console launch prefix -->
  <arg name="launch_prefix" default=""/>

  <!-- Config and weights folder. -->
  <arg name="yolo_weights_path"          default="$(find darknet_ros)/yolo_network_config/weights"/>
  <arg name="yolo_config_path"           default="$(find darknet_ros)/yolo_network_config/cfg"/>

  <!-- ROS and network parameter files -->
  <arg name="ros_param_file"             default="$(find darknet_ros)/config/ros.yaml"/>
  <arg name="network_param_file"         default="$(find darknet_ros)/config/yolov2-tiny.yaml"/>

  <!-- Load parameters -->
  <rosparam command="load" ns="darknet_ros" file="$(arg network_param_file)"/>
  <rosparam command="load" file="$(find darknet_ros)/config/ros.yaml"/>
  <param name="darknet_ros/subscribers/camera_reading/topic" type="string" value="$(arg camera_rgb_topic)" />

  <!-- Start darknet and ros wrapper -->
  <node pkg="darknet_ros" type="darknet_ros" name="darknet_ros" output="screen" launch-prefix="$(arg launch_prefix)">

    <param name="weights_path"          value="$(arg yolo_weights_path)" />
    <param name="config_path"           value="$(arg yolo_config_path)" />
  </node>

  <!-- Start darknet ros 3d -->
  <node pkg="darknet_ros_3d" type="darknet3d_node" name="darknet_3d" output="screen">
    <rosparam command="load" file="$(find my_object_recognition_pkg)/config/darknet_3d.yaml" />
  </node>
</launch>
darknet_3d.yaml
darknet_ros_topic: /darknet_ros/bounding_boxes
output_bbx3d_topic: /darknet_ros_3d/bounding_boxes
point_cloud_topic: /camera/depth_registered/points
working_frame: camera_rgb_optical_frame
mininum_detection_thereshold: 0.3
minimum_probability: 0.3
interested_classes: ["person", "elephant", "horse", "bottle", "toothbrush", "traffic light", "spoon", "scissors"]

 

<arg name="camera_rgb_topic" default="/camera/rgb/image_raw" />

我们需要设置输入 RGB 原始相机。

<arg name="network_param_file"         default="$(find darknet_ros)/config/yolov2-tiny.yaml"/>

在这里,我们将再次设置 v2 Tiny。它速度很快,特别是如果你想在 RViz 中查看点云(这将对系统负载产生显着影响)。这是最好的选择。 

<rosparam command="load" file="$(find my_object_recognition_pkg)/config/darknet_3d.yaml" />

 加载 darknet_3d 的参数。设置以下内容:

  • point_cloud_topic:这是您的机器人发布点云数据的 ROS 主题。这用于匹配 2D 中的 RGB 检测和 3D 中的点云数据以生成 3D 中的边界框。
  • minimum_probability 和 mininum_detection_thereshold:我们设置我们认为有效的检测并生成边界框。
  • interested_classes:这些是您要搜索的对象。由于系统负载影响,值越低越好。这里我们设置了人和大象。

但是我们如何知道 YOLO v2 Tiny 可以检测到哪个对象?检查下面的文件:

roscd darknet_ros/config
cat yolov2-tiny.yaml

 开始启动并查看输出:

# Set variables only for this course, locally you wont need it
QT_X11_NO_MITSHM=1
echo $QT_X11_NO_MITSHM
# Start yolo V3
roslaunch my_object_recognition_pkg darknet_ros_3d.launch

 现在您可以打开 RViz,添加 RobotModel、PointCloud2 和 MarkerArray(用于可视化检测)。您也可以从 Perception Course Solutions Git 中加载它,位于 /perception_unit3_solutions/my_object_recognition_pkg/rviz/y

练习 3.5.1

  • 创建一个名为 yolo_3d_data_extraction.py 的 Python 脚本,该脚本提取由 darknet_ros_3d.launch 生成的标记数据并仅过滤您想要的对象。在本例中为大象。
  • 它必须能够存储同一类型的多个对象(尝试使用人)。
  • 提取数据的主题是 /darknet_ros_3d/bounding_boxes。
  • 您必须根据最大值和最小值计算边界框的中心。

请记住在 Python 脚本中使 Python 脚本可执行,以便 ROS 可以执行它:

roscd my_object_recognition_pkg
touch scripts/yolo_3d_data_extraction.py
chmod +x yolo_3d_data_extraction.py
 my_object_recognition_pkg/scripts/yolo_3d_data_extraction.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
from gb_visual_detection_3d_msgs.msg import BoundingBoxes3d

class Yolo3DFilter:

   def __init__(self, object_name_to_search, accepted_probability=0.2):

      self._rate = rospy.Rate(5)

      self._object_name_to_search = object_name_to_search
      self._accepted_probability = accepted_probability
      self.objects_dict = {}
      self.yolo_3d_topic = "/darknet_ros_3d/bounding_boxes"
      self._check_yolo_3d_ready()
      rospy.Subscriber(self.yolo_3d_topic, BoundingBoxes3d, self.yolo_3d_clb)
     
      rospy.loginfo('Ready to detect with Yolo!')

   def _check_yolo_3d_ready(self):
      yolo_3d_data = None
      while yolo_3d_data is None and not rospy.is_shutdown():
         try:
               yolo_3d_data = rospy.wait_for_message(self.yolo_3d_topic, BoundingBoxes3d, timeout=1.0)
               rospy.logdebug("Current "+self.yolo_3d_topic+" READY=>" + str(yolo_3d_data))

         except:
               rospy.logerr("Current "+self.yolo_3d_topic+" not ready yet, retrying.")

   def update_object_name_to_search(self,new_name):
      self._object_name_to_search = new_name

   def calculate_center(self,box_data):

      x_center = (box_data.xmin + box_data.xmin) / 2.0
      y_center = (box_data.ymin + box_data.ymin) / 2.0
      z_center = (box_data.zmin + box_data.zmin) / 2.0

      return [x_center, y_center, z_center]

   def yolo_3d_clb(self, msg):

      # We clean the dict
      self.objects_dict = {}
      detect_object_index = 0

      detection_boxes_array = msg.bounding_boxes
      
      for box in detection_boxes_array:
         object_name = box.Class
         detection_probability = box.probability
         if object_name == self._object_name_to_search:
            if detection_probability >= self._accepted_probability:
               center_array = self.calculate_center(box)  
               unique_object_name = object_name+str(detect_object_index)             
               self.objects_dict[unique_object_name] = center_array
               
               detect_object_index += 1
            else:
               rospy.logdebug("Probability too low=="+str(detection_probability)+"<"+str(self._accepted_probability))
         else:
            rospy.logdebug("Object name doenst match="+str(object_name)+","+str(self._object_name_to_search))


   def get_objects_dict_detected(self):
      return self.objects_dict

   def run(self):


      while not rospy.is_shutdown():
         searched_for_objects_detected = self.get_objects_dict_detected()
         rospy.loginfo(str(searched_for_objects_detected))
         self._rate.sleep()



if __name__ == '__main__':
   rospy.init_node('searhc_for_object_node', log_level=rospy.INFO)
   yolo_obj = Yolo3DFilter(object_name_to_search="person")

   try:
      yolo_obj.run()
   except KeyboardInterrupt:
      rospy.loginfo('Shutting down')


原文地址:https://blog.csdn.net/qq_44188415/article/details/142398242

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!