批量计算地图弓字路径
批量计算地图弓字路径
分析:
对每个cell都会计算旋转方向;cell之间的路径直接使用直线连接起来的;
另外有一些操作值得借鉴,例如对轮廓的搜索,小的cell的合并和去除;
去除边缘噪点,纠正断断续续的墙;
void BoustrophedonExplorer::correctThinWalls(cv::Mat& room_map) { for (int v=1; v<room_map.rows; ++v) { for (int u=1; u<room_map.cols; ++u) { if (room_map.at<uchar>(v-1,u-1)==255 && room_map.at<uchar>(v-1,u)==0 && room_map.at<uchar>(v,u-1)==0 && room_map.at<uchar>(v,u)==255) room_map.at<uchar>(v,u)=0; else if (room_map.at<uchar>(v-1,u-1)==0 && room_map.at<uchar>(v-1,u)==255 && room_map.at<uchar>(v,u-1)==255 && room_map.at<uchar>(v,u)==0) room_map.at<uchar>(v,u-1)=0; } } }
路径稀疏化
void BoustrophedonExplorer::downsamplePath(const std::vector<cv::Point>& original_path, std::vector<cv::Point>& downsampled_path, cv::Point& robot_pos, const double path_eps) { // downsample path for(size_t path_point=0; path_point<original_path.size(); ++path_point) { if(cv::norm(robot_pos-original_path[path_point]) >= path_eps) { downsampled_path.push_back(original_path[path_point]); robot_pos = original_path[path_point]; } } // add last element if (original_path.size() > 0) { downsampled_path.push_back(original_path.back()); robot_pos = original_path.back(); } }
将多边形填充绘制到图片上
void drawPolygon(cv::Mat& image, const cv::Scalar& color) const { // draw polygon in an black image with necessary size cv::Mat black_image = cv::Mat(max_y_+10, max_x_+10, CV_8UC1, cv::Scalar(0)); #if CV_MAJOR_VERSION<=3 cv::drawContours(black_image, std::vector<std::vector<cv::Point> >(1,vertices_), -1, color, CV_FILLED); #else cv::drawContours(black_image, std::vector<std::vector<cv::Point> >(1,vertices_), -1, color, cv::FILLED); #endif // assign drawn map image = black_image.clone(); }
【great】优点:单独的cell会规划出长边优先的路径,而不是整个地图只有一个长边方向;
对于大的地图耗时很久;
改善
需要提前对地图做腐蚀膨胀;需用将所有的空洞都填充成黑色,不然一些不连通的白色区域会使用astar搜不到路径,很耗时;
todocell之间的转场需要使用astar路径衔接;或者不同cell的路径分开;
结果图片
规划出的路径在不同的cell会有不同的方向,上面这个结果里面cell可以直接作为分区使用,区分度很大
使用原图
在虚拟机
tang@tang-virtual-machine:~/Desktop/123MyProj/test_room_segmentation/test_ccpp/bin/showmaps$
或者电脑上如下位置
E:\recent_files\showmaps-spiral-zigzag