簡體   English   中英

Python 3:如何使用顏色表模糊GeoTIFF圖像?

[英]Python 3: How to blur a GeoTIFF image with color table?

我有一個GeoTIFF圖像,需要通過應用平滑濾鏡使其模糊。 圖像本身包含需要保留的元數據。 它的位深度為8,並且使用具有256個32位RGBA值的色表來為每個像素查找顏色,但是為了使所得圖像看起來更平滑,它可能必須使用的位深度。 24或32,並且沒有顏色表,或者使用jpeg壓縮。 可能使該情況進一步復雜化的是,該圖像的大小為23,899x18,330像素,幾乎是PIL默認情況下要打開的最大文件的五倍。

如何在Python 3中創建此圖像的模糊版本?

我也嘗試過使用PIL打開並再次保存它:

from PIL import Image
Image.MAX_IMAGE_PIXELS = 1000000000
im = Image.open(file_in)
im.save(file_out)

該代碼不會崩潰,並且我得到一個新的.tif文件,該文件大約與原始文件一樣大,但是當我嘗試在Windows Photo Viewer中打開它查看該文件時,應用程序說它已損壞,並且無法由PIL重新打開。

我也嘗試過使用GDAL。 嘗試此代碼時 ,我得到的輸出圖像是835 MB大,對應於位深度為16的未壓縮圖像(這也是我右鍵單擊它並選擇“屬性“ –我正在使用Windows 10)。 但是,生成的圖像是單色且非常暗,顏色看起來像是被弄亂了,這使我相信我正在嘗試的代碼將像素值解釋為強度值,而不是表鍵。

因此,為了使此方法可行,我需要弄清楚如何將顏色表(某種類型的元組容器,類型為osgeo.gdal.ColorTable )應用於柵格波段(無論柵格波段是什么),它是形狀為(18330, 23899) numpy數組,以獲得形狀為(18330, 23899, 4)(4, 18330, 23899) (18330, 23899)的新numpy數組(不知道哪個是正確的形狀),將此圖像重新插入到已加載的圖像中,並刪除顏色表(或使用相同的元數據創建一個新的顏色表),最后在啟用壓縮的情況下保存修改后的圖像(因此我更接近原始文件大小– 11.9 MB –而不是835) MB,即我現在得到的文件大小)。 我怎樣才能做到這一點?

pyvips可以僅使用少量內存就可以快速處理巨大的圖像,並支持調色板TIFF圖像。

不幸的是,它不支持額外的geotiff標簽,因為libtiff不適用於未知標簽類型。 您需要以其他方式復制該元數據。

無論如何,如果可以的話,pyvips應該可以在您的圖像上工作。 我試過這個例子:

import sys
import pyvips

# the 'sequential' hint tells libvips that we want to stream the image
# and don't need full random access to pixels ... in this mode, 
# libvips can read, process and write in parallel, and without needing
# to hold the whole image in memory
image = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
image = image.gaussblur(2)
image.write_to_file(sys.argv[2])

在您擁有的類型和大小的圖像上,生成JPEG壓縮的TIFF:

$ tiffinfo x2.tif 
TIFF Directory at offset 0x1a1c65c6 (438068678)
  Image Width: 23899 Image Length: 18330
  Resolution: 45118.5, 45118.5 pixels/cm
  Bits/Sample: 8
  Compression Scheme: None
  Photometric Interpretation: palette color (RGB from colormap)
...
$ /usr/bin/time -f %M:%e python3  ~/try/blur.py x2.tif x3.tif[compression=jpeg]
137500:2.42

因此140MB的內存需要2.5秒。 輸出圖像看起來正確,大小為24mb,因此離您的圖像不太遠。

光柵帶只是賦予圖像每個“層”的名稱,在您的情況下,它們將是紅色,綠色,藍色和Alpha值。 這些就是您要模糊的內容。 您可以打開圖像,並使用data.GetRasterBand(i)將每個波段保存到單獨的數組中,以獲取使用GDAL打開的圖像的第i個波段(使用1索引而不是 0索引)。

然后,您可以嘗試使用SciPy的scipy.ndimage.gaussian_filter實現模糊效果。 您將需要向其發送形狀為(x,y)的數組,因此必須分別對每個柵格波段執行此操作。 您應該可以使用GDAL將數據另存為另一個GeoTIFF。


如果您正在使用的色表意味着您的數據以某種奇怪的格式存儲在每個光柵帶中,而不僅僅是R,G,B和A中的每個在0和1之間浮動,那么請考慮使用scipy.ndimage.generic_filter ,盡管不知道數據的存儲方式,但很難給出具體方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM