通过基于统计数据汇总5x5像素来缩小TIFF图像

发布于 2025-02-08 22:15:30 字数 558 浏览 3 评论 0 原文

如何降低10m分辨率的TIFF映像,并创建一个50m的新图像,每个像素是第一个图像的统计信息?

初始TIFF映像是二进制分类图 - 意味着每个像素(10m)属于“水”(值= 0)或类“ ICE”(值= 1)的类。 我想创建一个新图像,其中每个像素是初始地图的5 x 5块中水百分比,这意味着新图像的每个像素都将具有50 m的分辨率,并且表示“水的比率或百分比” “以前地图的每5x5像素上的像素。您可以在此处看到示例:示例

这是一个映像示例(可以从Google驱动器下载):

How to downscale a tiff image of 10m resolution and create a new image of 50m where each pixel is stats from the first image?

The initial tiff image is a binary classification map - meaning each pixel (10m) belongs either to class "water" (value =0) or class "ice" (value=1).
I would like to create a new image, where each pixel is the percentage of water in a 5 x 5 block of the initial map, meaning each pixel of the new image will have a 50 m resolution and represents the ratio or percentage of "water" pixel on every 5x5 pixel of the former map. You can see the example here: Example

Here is an image sample (can be downloaded from google drive):
https://drive.google.com/uc?export=download&id=19hWQODERRsvoESiUZuL0GQHg4Mz4RbXj

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江南月 2025-02-15 22:15:30

您的图像以一种相当奇怪的格式保存,使用32位浮子仅表示可以用一点点表示的两类数据,因此我用 imagemagick 使用:

magick YOURIMAGE.TIF -alpha off image.png

许多Python库会在您的实际TIFF上结结巴巴,因此也许要考虑使用另一种编写方式。

完成此操作后,代码可能看起来像这样:

#!/usr/bin/env python3

from PIL import Image
import numpy as np

# Set size of tiles for subsampling
tileX = tileY = 5

# Open image and convert to greyscale and thence to Numpy array
im = Image.open('image.png').convert('L')
na = np.array(im)

# Round height and width down to next lower multiple of tile sizes
h = (na.shape[0] // tileY) * tileY
w = (na.shape[1] // tileX) * tileX

# Create empty output array to fill
res = np.empty((h//tileY,w//tileX), np.uint8)

pxPerTile = tileX * tileY
for yoffset in range(0,h,tileY):
    for xoffset in range(0,w,tileX):
        # Count ice pixels in this 5x5 tile
        nonZero = np.count_nonzero(na[yoffset:yoffset+tileY, xoffset:xoffset+tileX])
        percent = int((100.0 * (pxPerTile - nonZero))/pxPerTile)
        res[yoffset//tileY, xoffset//tileX] = percent

# Make Numpy array back into PIL Image and save
Image.fromarray(res.astype(np.uint8)).save('result.png')

”在此处输入图像描述


在反射上,您可以更快地进行操作,而更简单地使用

Your image is saved in a rather odd format, using a 32-bit float to represent just two classes of data which could be represented in a single bit, so I converted it to PNG with ImageMagick using:

magick YOURIMAGE.TIF -alpha off image.png

Many Python libraries will stutter on your actual TIFF so maybe think about using a different way of writing it.

Once that is done, the code might look something like this:

#!/usr/bin/env python3

from PIL import Image
import numpy as np

# Set size of tiles for subsampling
tileX = tileY = 5

# Open image and convert to greyscale and thence to Numpy array
im = Image.open('image.png').convert('L')
na = np.array(im)

# Round height and width down to next lower multiple of tile sizes
h = (na.shape[0] // tileY) * tileY
w = (na.shape[1] // tileX) * tileX

# Create empty output array to fill
res = np.empty((h//tileY,w//tileX), np.uint8)

pxPerTile = tileX * tileY
for yoffset in range(0,h,tileY):
    for xoffset in range(0,w,tileX):
        # Count ice pixels in this 5x5 tile
        nonZero = np.count_nonzero(na[yoffset:yoffset+tileY, xoffset:xoffset+tileX])
        percent = int((100.0 * (pxPerTile - nonZero))/pxPerTile)
        res[yoffset//tileY, xoffset//tileX] = percent

# Make Numpy array back into PIL Image and save
Image.fromarray(res.astype(np.uint8)).save('result.png')

enter image description here


On reflection, you can probably do it faster and more simply with cv2.resize() and a decimation of 0.2 on both axes and interpolation cv2.INTER_AREA

凶凌 2025-02-15 22:15:30

我在

#!/usr/bin/python3

import sys
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1])

# label (0 == water, 1 == ice) is in the first band
label = image[0]

# average 5x5 areas
label = label.shrink(5, 5)

# turn into a percentage of water
water_percent = 100 * (1 - label)

# ... and save
water_percent.write_to_file(sys.argv[2])

版本

$ ./average.py ~/pics/meltPondClassifiedAndS12.tif x.png

一个 (相反)输出:

”在此处输入图像描述”

I did a version in pyvips:

#!/usr/bin/python3

import sys
import pyvips

image = pyvips.Image.new_from_file(sys.argv[1])

# label (0 == water, 1 == ice) is in the first band
label = image[0]

# average 5x5 areas
label = label.shrink(5, 5)

# turn into a percentage of water
water_percent = 100 * (1 - label)

# ... and save
water_percent.write_to_file(sys.argv[2])

I can run it on your test image like this:

$ ./average.py ~/pics/meltPondClassifiedAndS12.tif x.png

To make this (rather dark) output:

enter image description here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文