簡體   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