AGV栅格地图与QImage图片转换笔记

最近在加班加点处理一个agv相关的任务,印象比较深的是将agv给的json数据转换为一个图片。最终的简化需求是将某坐标系下的二维点数据转换为一张图片的像素。Ok,首先的问题是如何将二维的数据映射到栅格坐标系。先看数据例子:

"mapType":"2D-Map","maxPos":{"x":4.51,"y":16.331},"minPos":{"x":-14.138,"y":-1.48}
"resolution":0.02
"normalPosList":[{"x":-14.138,"y":9.303},{"x":-14.099,"y":9.324},
{"x":-13.699,"y":9.337},{"x":-13.679,"y":9.318},{"x":-13.668,"y":9.598},
{"x":-13.648,"y":9.599},{"x":-13.627,"y":9.56},{"x":-13.619,"y":9.34}]

随便截取的一些,实际有很多。这是经过放缩后的数据,实际建的图很大,所以还有resolution这个参数。

通过maxPos减去minPos,可以得到点的二维最值范围,以此来得到整张地图的范围,通过resolution的放缩就可以与实际地图相对应。再进一步 ,地图变成了“栅格”,将坐标点的位置“涂黑”,就得到了这些点的可视化位置;我们知道一张图片是有像素点组成的,也可以理解为是个二维数组(Qt  QImage的像素点是在左上角原点)。如果用0和1表示“二值化”的黑白图,那么用0-255则可以表示“灰度图”,255是全白,这些作为前置知识,很多工作中的新问题需要快速解决,后面再逐步学习更进一步的知识原理。到现在,首先要将坐标值映射到到“栅格坐标系”;栅格“是一张m*n”的“格子”,二维坐标原点与栅格原点不不一致,将每个点二维坐标减去最值坐标(得出来的新坐标就是基于“栅格坐标系”的了)再通过resolution还原,将该坐标存储记录。有点绕,坐标值减去最值,相当于将原来坐标轴平移了,这样新坐标就是基于“栅格坐标系”的了。    

338eb1a8f7050a326953f836d9557eb1.jpeg

这是一张目标图片,记图1。

QImage grayImg1 (width, height+100, QImage::Format_Grayscale8);
    grayImg1.fill(qRgb(255, 255, 255));
    for ( int i = 0; i < height; i++) {
        for ( int j = 0; j < width; j++) {
            if (normal_grids.at(i).at(j) > 0) {
                int gray = 0;
                grayImg1.setPixelColor(j, i, QColor(gray, gray, gray));
            }
        }
    }

上述代码将栅格的高和宽作为图片像素的高和宽,在setPixelColor时,先i后j,即先高后宽(先列后行),效果如图3。不过都不是我们想要,但是将图3上下反转180度就是我们想要的了,有意义的错误,最主要还是原理理解不清楚,这需要一个和过程,期间甚至将二维数组绕对角线变换,行做inverse变换,列做reverse变换,然后突然想到将QImage setPixelColor行列变换,那会意识到inverse是做180度变换,发现达不到效果。    

b7aae40f89b645b74856bbfeabfdec71.png

这是一张将栅格坐标转为像素坐标后用QImage显示出来的,记为图2。图2需要逆时针旋转90度才能变为图1。

b863804e4953876de6020c82794ffab5.png

图3,与图2相比,向右旋转了90度。    

fd5fe1adfa2ebf2152878caa4a725337.png

目标效果图,即为图4。行做inverse变换,在setPixelColor时,先j后i。

即二维数组可以认为是一个图像,其变换也就是图像变换。供大家参考。    

栅格地图是一种将环境划分为规则格子的形式来表示的二维地图。在这种地图中,每个格子可以被标记为可通行或不可通行,用以表示障碍物和其他特征。AGV(自动引导车)路径规划是指在这样的栅格地图上找到从起点到终点的一条有效路径,同时要尽量避免碰撞障碍物,并可能需要满足其他诸如最短距离、最少转弯次数等优化条件。 在Python中进行AGV路径规划,我们通常会采用一些算法来实现,比如A*算法、Dijkstra算法或者深度优先搜索(DFS)算法等。以A*算法为例,这是一种启发式搜索算法,它结合了最好优先搜索和Dijkstra算法的优点。A*算法使用一个估价函数f(n) = g(n) + h(n),其中g(n)是从起点到当前点的实际代价,而h(n)是从当前点到目标点的估计代价。h(n)通常是启发式的,例如使用欧几里得距离或者曼哈顿距离作为估计。 下面是一个简单的A*算法实现栅格地图AGV路径规划的Python代码示例(注意:这个示例仅供参考,实际应用中需要根据具体环境进行调整): ```python import heapq class Node: def __init__(self, parent=None, position=None): self.parent = parent self.position = position self.g = 0 self.h = 0 self.f = 0 def __eq__(self, other): return self.position == other.position def __lt__(self, other): return self.f < other.f def astar(maze, start, end): start_node = Node(None, tuple(start)) end_node = Node(None, tuple(end)) open_list = [] closed_list = set() heapq.heappush(open_list, start_node) while open_list: current_node = heapq.heappop(open_list) closed_list.add(current_node) if current_node == end_node: path = [] while current_node: path.append(current_node.position) current_node = current_node.parent return path[::-1] # Return reversed path children = [] for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0)]: # Adjacent squares node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1]) if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0: continue if maze[node_position[0]][node_position[1]] != 0: continue new_node = Node(current_node, node_position) children.append(new_node) for child in children: if child in closed_list: continue child.g = current_node.g + 1 child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2) child.f = child.g + child.h if len([open_node for open_node in open_list if child == open_node and child.g > open_node.g]) > 0: continue heapq.heappush(open_list, child) return None # Example usage: maze = [[0, 0, 0, 0, 1], [1, 1, 0, 1, 0], [0, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 1, 0]] start = [0, 0] end = [4, 4] path = astar(maze, start, end) print(path) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值