mobile wallpaper 1
mobile wallpaper 2
mobile wallpaper 3
mobile wallpaper 4
278 字
1 分钟
ipa_coverage_planning 算法解读(一)
2024-07-17
2024-08-08

ipa_room_segmentation (地图分割,用于房间分区)#

客户端 room_segmentation_client.cpp#

头文件

#include <ros/ros.h>
// 提供了ROS节点的基本功能,如初始化节点、发布和订阅消息等。
#include <ros/package.h>
// 提供了与ROS包管理相关的功能,例如获取包路径。
#include <string>
#include <vector>
// C++标准库的头文件,用于处理字符串和向量数据结构。
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
// OpenCV库的头文件,用于图像处理和图形用户界面功能。
#include <cv_bridge/cv_bridge.h>
// cv_bridge库的一部分,它提供了ROS图像消息和OpenCV图像格式之间转换的功能
#include <actionlib/client/simple_action_client.h>
#include <actionlib/client/terminal_state.h>
// actionlib库的头文件,用于实现ROS中的动作服务器和客户端
#include <ipa_building_msgs/MapSegmentationAction.h>
// 房间分割任务相关的自定义消息类型和服务
#include <ipa_room_segmentation/dynamic_reconfigure_client.h>
// 动态重新配置房间分割服务的客户端接口

main 客户端是直接把测试地图名写入一个 vector 变量 map_names 中,然后在 for 循环中在指定地址获取相应的地图地址,把地图转为地图话题数据,再装入 goal 中发送给服务端。 设置Ros环境并创建一个节点,一边程序可以与Ros网络中的其他节点进行交互

ros::init(argc, argv, "room_segmentation_client");
ros::NodeHandle nh;

添加地图表,每一个都是对应文件中的地图图像文件名

// map names
std::vector< std::string > map_names;
map_names.push_back("lab_ipa");
map_names.push_back("lab_c_scan");
...

整个函数围绕这个for循环进行

for (size_t image_index = 0; image_index<map_names.size(); ++image_index) {
// 在 ipa_room_segmentation 功能包的指定位置搜索地图
std::string image_filename = ros::package::getPath("ipa_room_segmentation") + "/common/files/test_maps/" + map_names[image_index] + ".png";
cv::Mat map = cv::imread(image_filename.c_str(), 0); // cv 读地图
...
cv_image.toImageMsg(labeling); // 数据转换
actionlib::SimpleActionClient<ipa_building_msgs::MapSegmentationAction> ac("room_segmentation_server", true);
... // goal 数据装包
ac.sendGoal(goal); // 目标发送到服务端
bool finished_before_timeout = ac.waitForResult(ros::Duration()); // 等待结果
if (finished_before_timeout) {
... // 数据转换到 cv 格式
cv::imshow("segmentation", colour_segmented_map); // cv 显示地图
cv::waitKey(); // 敲空格测试下一张地图
}
}

详细解释for中的代码 这段代码展示了如何在ROS(Robot Operating System)中使用OpenCV库来导入图像文件。具体来说,它是从一个特定的路径加载图像文件到cv::Mat对象中

// import maps
std::string image_filename = ros::package::getPath("ipa_room_segmentation") + "/common/files/test_maps/" + map_names[image_index] + ".png";
cv::Mat map = cv::imread(image_filename.c_str(), 0);

二值化,将图像中小于255的全部设置为0,即非白即黑

for (int y = 0; y < map.rows; y++)
{
for (int x = 0; x < map.cols; x++)
{
//find not reachable regions and make them black
if (map.at<unsigned char>(y, x) < 250)
{
map.at<unsigned char>(y, x) = 0;
}
//else make it white
else
{
map.at<unsigned char>(y, x) = 255;
}
}
}

这段代码展示了如何使用cv_bridge库将OpenCV的图像格式转换为ROS的sensor_msgs::Image消息格式

//声明了一个sensor_msgs::Image类型的变量labeling,这是ROS中用于表示图像的标准消息类型。
sensor_msgs::Image labeling;
//声明了一个cv_bridge::CvImage类型的变量cv_image。CvImage是cv_bridge中的一个类,用于在ROS消息和OpenCV图像之间进行转换
cv_bridge::CvImage cv_image;
//这行代码被注释掉了,但如果取消注释,它会设置cv_image的时间戳为当前时间
//cv_image.header.stamp = ros::Time::now();
//设置cv_image的编码格式为"mono8",这表示图像是以8位单通道(灰度)格式存储的。
cv_image.encoding = "mono8";
//将OpenCV图像map赋值给cv_image的image成员。这里的map是一个cv::Mat类型的变量,包含了要转换的图像数据。
cv_image.image = map;
//这个函数调用将cv_image中的OpenCV图像转换为ROS的sensor_msgs::Image消息,并将结果存储在labeling变量中。
cv_image.toImageMsg(labeling);
分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ipa_coverage_planning 算法解读(一)
https://ericonline.cn/posts/ipa_coverage_planning-算法解读一/
作者
Eric
发布于
2024-07-17
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录