繁体   English   中英

为什么 gdal_grid 将图像上下颠倒?

[英]Why does gdal_grid turn image upside-down?

我正在尝试使用 gdal_grid 从 geojson 中的表面制作高程网格。 我使用这个命令:

gdal_grid -a linear:radius=0 inputSurface.geojson outputFile.tif

它似乎给出了正确的像素值,但如果我在 Global Mapper 或 QGIS 中打开结果,图像会在水平轴上翻转/镜像,这样 tif 就在表面正下方并上下颠倒。 这是什么原因,我该如何解决?

更新

我已经尝试更改地理变换,但它并没有完全解决我的问题。

我在 gdalinfo 中查看了生成的图像,发现左上角实际上是左下角,因此我使用 SetGeoTransform 设置它。 这将它移动到正确的位置,但它仍然是颠倒的。 (这可能取决于投影,这可能会导致以后出现问题)

我还尝试查看 geotransform 中的像素宽度,如下所述:

Xgeo = GT[0] + Xpixel*GT[1] + Yline*GT[2]
Ygeo = GT[3] + Xpixel*GT[4] + Yline*GT[5]

gdal_grid 返回的图像具有正 GT[5],但不幸的是,将其更改为 -GT[5] 不会改变任何内容。

我用来改变地理变换的代码:

transform = list(ds.GetGeoTransform())
transform = [upperLeftX, transform[1], 0, upperLeftY, 0, -transform[5]]
ds.SetGeoTransform(transform)

GDAL 的地理配准通常由两组参数指定。 第一个是空间参考,它定义了坐标系(UTM、WGS,更局部的东西)。 使用gdal.Dataset.setProjection()设置栅格的空间参考。 第二个地理配准是 GeoTransform,它将(行、列)像素索引转换为坐标系中的坐标。 您可能需要更新地理变换以使图像“未翻转”。

GeoTransform 是一个包含 6 个值的元组,它将栅格索引与坐标相关联。

Xgeo = GT[0] + Xpixel*GT[1] + Yline*GT[2]
Ygeo = GT[3] + Xpixel*GT[4] + Yline*GT[5]

因为这些是光栅图像,所以 (line, pixel) 或 (row, col) 坐标从图像的左上角开始。

[ ]----> column
 |
 |
 v row

这意味着当图像在坐标系中“直立”定位时, GT[1]将为正。 类似地,有时与直觉相反, GT[5]将为负数,因为图像中每增加一行,y 值都应减少。 这不是必需的,但很常见。

修改地理变换

您声明图像上下颠倒并低于应该的位置。 这不能保证是一个修复,但它会让你开始。 如果您面前有图像并且可以实验或比较坐标,那就更容易了...

import gdal
# open dataset as readable/writable
ds = gdal.Open('input.tif', gdal.GA_Update)
# get the GeoTransform as a tuple
gt = gdal.GetGeoTransform()
# change gt[5] to be it's negative, flipping the image
gt_new = (gt[0], gt[1], gt[2], gt[3], gt[4], -1 * gt[5])
# set the new GeoTransform, effectively flipping the image
ds.SetGeoTransform(gt_new)
# delete the dataset reference, flushing the cache of changes
del ds

我最终在 gdal_grid 上遇到了更多问题,它只是在看似随机的地方崩溃,所以我改用名为 griddata 的 scipy.interpolate 函数。 这使用meshgrid来获取网格中的坐标,由于meshgrid的内存限制,我不得不将其平铺。

import scipy.interpolate as il #for griddata
import numpy as np
# meshgrid of coords in this tile
gridX, gridY = np.meshgrid(xi[c*tcols:(c+1)*tcols], yi[r*trows:(r+1)*trows][::-1])

## Creating the DEM in this tile
zi = il.griddata((coordsT[0], coordsT[1]), coordsT[2], (gridX, gridY),method='linear',fill_value = nodata) # fill_value to prevent NaN at polygon outline
raster.GetRasterBand(1).WriteArray(zi,c*tcols,nrows-r*trows-rtrows)

线性插值似乎与 gdal_grid 应该做的一样。 这实际上是通过将 geotransform 中的第 5 个元素设为负值来实现的,如问题更新中所述。

请参阅scipy.interpolate.griddata 中的说明。

需要注意的几点:

  1. 地理变换中使用的点应该在左上角
  2. y 方向的分辨率应为负
  3. 在投影中(至少是我使用的)正 y 方向向上
  4. 在 numpy 数组中,正 y 方向向下
  5. 使用 gdal 的 WriteArray 时,它使用左上角

希望这有助于其他人的困惑。

我通过简单地重新投影 gdal_grid 的结果解决了类似的问题。 试一试(用您的投影替换 epsg 代码并替换输入/输出文件路径):

gdalwarp -s_srs epsg:4326 -t_srs epsg:4326 gdal_grid_result.tif inverted_output.tif

它没有。 它只是呈现它的工具的标准。 尝试在 QGIS 中打开它,你会注意到它是正面朝上的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM