最近在加班加点处理一个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还原,将该坐标存储记录。有点绕,坐标值减去最值,相当于将原来坐标轴平移了,这样新坐标就是基于“栅格坐标系”的了。
这是一张目标图片,记图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度变换,发现达不到效果。
这是一张将栅格坐标转为像素坐标后用QImage显示出来的,记为图2。图2需要逆时针旋转90度才能变为图1。
图3,与图2相比,向右旋转了90度。
目标效果图,即为图4。行做inverse变换,在setPixelColor时,先j后i。
即二维数组可以认为是一个图像,其变换也就是图像变换。供大家参考。