使用 OpenCV 绘制 ROS markerArrays?

问题描述 投票:0回答:0

我有一个带有 markerArray 标记的 ROS 包文件,我试图在图像上绘制它(这样我以后可以用作边界框)。

数据来自车辆的行程(进入高速公路匝道,绕行,然后驶出高速公路)。

这是 RViz 中标记的样子(我的车辆是 3.40m 的中间立方体):

我尝试使用以下代码使用 OpenCV 绘制立方体标记(红色立方体):

#include <rosbag/bag.h>
#include <rosbag/view.h>
#include <visualization_msgs/MarkerArray.h>
#include <opencv2/opencv.hpp>
#include <boost/filesystem.hpp>

int main(int argc, char** argv)
{
  // Open the ROS bag file
  rosbag::Bag bag;
  bag.open("/home/awfwiswasi/aioi-atg/ros_markers/rosbag_000.bag", rosbag::bagmode::Read);

// Specify the topic that contains the marker array data
std::vector<std::string> topics;
topics.push_back("/paccar/objects_marker");

// Create a view of the ROS bag file containing the specified topic
rosbag::View view(bag, rosbag::TopicQuery(topics));

// Create a directory to store the image frames
std::string image_dir = "/home/awfwiswasi/aioi-atg/ros_markers/image_frames";
if (!boost::filesystem::exists(image_dir))
{
  boost::filesystem::create_directory(image_dir);
}

// Loop through the messages in the view
int frame_num = 0;
for (rosbag::MessageInstance const msg : view) {
  // Convert the message to a marker array
 visualization_msgs::MarkerArray::ConstPtr markers = msg.instantiate<visualization_msgs::MarkerArray>();

if (markers != NULL) {
  // Create an empty image to draw the markers on
  cv::Mat image = cv::Mat::zeros(480, 640, CV_8UC3);

  // Loop through the markers in the array
  for (int i = 0; i < markers->markers.size(); i++) {
    // Get the marker properties
    int id = markers->markers[i].id;
    int type = markers->markers[i].type;
    // Create a YUV422 color from the RGB values

    cv::Scalar color(8, 8, 240, 1);
    // Draw the marker on the image
    if (type == visualization_msgs::Marker::CUBE) {
      cv::Point3d position(markers->markers[i].pose.position.x, markers->markers[i].pose.position.y,
                           markers->markers[i].pose.position.z);

      cv::Vec3d scale(markers->markers[i].scale.x, markers->markers[i].scale.y, markers->markers[i].scale.z);
      cv::Matx33d rotation(markers->markers[i].pose.orientation.w, markers->markers[i].pose.orientation.z,
                           -markers->markers[i].pose.orientation.y,
                           -markers->markers[i].pose.orientation.z, markers->markers[i].pose.orientation.w,
                           markers->markers[i].pose.orientation.x,
                           markers->markers[i].pose.orientation.y, -markers->markers[i].pose.orientation.x,
                           markers->markers[i].pose.orientation.w);

      cv::Vec3d half_scale = scale * 2;

      // 8 points because Cube markers have 8 vertices
      cv::Vec3d points[8] = {cv::Vec3d(half_scale[0], half_scale[1], half_scale[2]),
                             cv::Vec3d(-half_scale[0], half_scale[1], half_scale[2]),
                             cv::Vec3d(half_scale[0], -half_scale[1], half_scale[2]),
                             cv::Vec3d(-half_scale[0], -half_scale[1], half_scale[2]),
                             cv::Vec3d(half_scale[0], half_scale[1], -half_scale[2]),
                             cv::Vec3d(-half_scale[0], half_scale[1], -half_scale[2]),
                             cv::Vec3d(half_scale[0], -half_scale[1], -half_scale[2]),
                             cv::Vec3d(-half_scale[0], -half_scale[1], -half_scale[2])};

      for (int j = 0; j < 8; j++) {
        points[j] = rotation * points[j] + cv::Vec3d(position.x, position.y, position.z);
      }
      cv::Point image_points[8];
      for (int j = 0; j < 8; j++) {
        image_points[j] = cv::Point(points[j][0], points[j][1]);
      }
      cv::fillConvexPoly(image, image_points, 8, color);
    }
  }

  // Write the image to a file
  std::string image_path = image_dir + "/" + std::to_string(frame_num) + ".png";
  cv::imwrite(image_path, image);

  // Increment the frame number
  frame_num++;
  }
}
// Close the ROS bag file
bag.close();

return 0;
}

这就是绘制的标记的样子:

现在我明白问题可能是标记记录在现实世界的变换坐标中,因此它们是这样绘制的。

如果我在我的代码中正确绘制它们,有人能告诉我是否有办法在相机变换坐标中绘制它们(从我的车辆向前看道路的前视图中查看它们)?

谢谢!

c++ opencv computer-vision ros rviz
© www.soinside.com 2019 - 2024. All rights reserved.