简体   繁体   English

从具有特定范围值的光栅图像中删除像素

[英]delete pixel from the raster image with specific range value

update: any idea how to delete pixel from specific range value raster image with using numpy/scipy or gdal ?更新:知道如何使用numpy/scipygdal从特定范围值光栅图像中删除像素吗?

or how to can create new raster with some class using raster calculation expressions (better)或者如何使用栅格计算表达式创建一些 class 的新栅格(更好)

for example i have a raster image with the 5 class:例如,我有一个光栅图像 5 class:

1. 0-100 
2. 100-200 
3. 200-300 
4. 300-500 
5. 500-1000 

and i want to delete class 1 range value or maybe class 1,2,4,5我想删除 class 1 个范围值或者 class 1,2,4,5

i begin with this script:我从这个脚本开始:

import numpy as np
from osgeo import gdal
ds = gdal.Open("raster3.tif")
myarray = np.array(ds.GetRasterBand(1).ReadAsArray())
#print myarray.shape
#print myarray.size
#print myarray
new=np.delete(myarray[::2], 1)

but i cant to complete但我无法完成

the image White in class 5 and black class 1 class 5 中的白色图像和 class 1 中的黑色图像

Rasters are 2-D arrays of values, with each value being stored in a pixel (which stands for picture element). 栅格是值的2维数组,每个值存储在一个像素中(代表像素)。 Each pixel must contain some information. 每个像素必须包含一些信息。 It is not possible to delete or remove pixels from the array because rasters are usually encoded as a simple 1-dimensional string of bits. 由于栅格通常被编码为简单的一维位串,因此无法从阵列中删除或删除像素。 Metadata commonly helps explain where line breaks are and the length of the bitstring, so that the 1-D bitstring can be understood as a 2-D array. 元数据通常有助于说明换行符在哪里以及位串的长度,以便将一维位串理解为二维数组。 If you "remove" a pixel, then you break the raster. 如果“删除”像素,则会破坏栅格。 The 2-D grid is no longer valid. 二维栅格不再有效。

Of course, there are many instances where you do want to effectively discard or clean the raster of data. 当然,在很多情况下,您确实希望有效地丢弃或清理数据栅格。 Such an example might be to remove pixels that cover land from a raster of sea-surface temperatures. 这样的示例可能是从海面温度栅格中删除覆盖陆地的像素。 To accomplish this goal, many geospatial raster formats hold metadata describing what are called NoData values. 为了实现此目标,许多地理空间栅格格式均包含描述所谓的NoData值的元数据。 Pixels containing a NoData value are interpreted as not existing. 包含NoData值的像素被解释为不存在。 Recall that in a raster, each pixel must contain some information. 回想一下,在栅格中,每个像素必须包含一些信息。 The NoData paradigm allows the structure and format of rasters to be met, while also giving a way to mask pixels from being displayed or analyzed. NoData范式可以满足栅格的结构和格式,同时还提供了一种掩盖显示或分析像素的方法。 There is still data (bits, 1s and 0s) at the masked pixels, but it only serves to identify the pixel as invalid. 被遮盖的像素处仍然有数据(位,1和0),但仅用于将像素标识为无效。

With this in mind, here is an example using gdal which will mask values in the range of 0-100 so they are NoData, and "do not exist". 考虑到这一点,这是一个使用gdal的示例,它将屏蔽0-100范围内的值,因此它们是NoData,并且“不存在”。 The NoData value will be specified as 0. NoData值将指定为0。

from osgeo import gdal

# open dataset to read, and get a numpy array
ds = gdal.Open("raster3.tif", 'r')
myarray = ds.GetRasterBand(1).ReadAsArray()
# modify numpy array to mask values
myarray[myarray <= 100] = 0

# open output dataset, which is a copy of original
driver = gdal.GetDriverByName('GTiff')
ds_out = driver.CreateCopy("raster3_with_nodata.tif", ds)
# write the modified array to the raster
ds_out.GetRasterBand(1).WriteArray(myarray)
# set the NoData metadata flag
ds_out.GetRasterBand(1).SetNoDataValue(0)
# clear the buffer, and ensure file is written
ds_out.FlushCache()

I want to contribute with an example for landsat data.我想贡献一个关于陆地卫星数据的例子。 In this qick guide, you will be able to exclude Landsat cloud pixels.在本快速指南中,您将能够排除 Landsat 云像素。 Landsat offers the Quality Assessment Band (BQA), which includes int32 values (classes) regarding natural features such as Clouds, Rocks, Ice, Water, Cloud Shadow etc. Landsat 提供质量评估带 (BQA),其中包括关于云、岩石、冰、水、云影等自然特征的 int32 值(类)。

We will use the BQA to clip the cloud pixels in the other bands.我们将使用 BQA 裁剪其他波段中的云像素。

# Import Packages
import rasterio as rio
import earthpy.plot as ep
from matplotlib import pyplot
import rioxarray as rxr
from numpy import ma

# Open the Landsat Band 3
Landsat_Image = rxr.open_rasterio(r"C:\...\LC08_L1TP_223075_20210311_20210317_01_T1_B3.tif")

# Open the Quality Assessment Band 
BQA = rxr.open_rasterio(r"C:\...\LC08_L1TP_223075_20210311_20210317_01_T1_BQA.tif").squeeze()

# Create a list with the QA values that represent cloud, cloud_shadow, etc.
Cloud_Values = [6816, 6848, 6896, 7072]

# Mask the data using the pixel QA layer
landsat_masked = Landsat_Image.where(~BQA.isin(Cloud_Values))
landsat_masked

# Plot the masked data
landsat_masked_plot = ma.masked_array(landsat_masked.values,landsat_masked.isnull())

# Plot
ep.plot_rgb(landsat_masked_plot, rgb=[2, 1, 0], title = "Masked Data")
plt.show()
###############################################################################
# Export the masked Landsat Scenes to Directory "Masked_Bands_QA"
out_img = landsat_masked
out_img.shape
out_transform = landsat_masked.rio.transform()

# Get a Band of the same Scene for reference
rastDat = rio.open(r"C:\Dados_Espaciais\NDVI_Usinas\Adeco\Indices\Imagens\LC08_L1TP_223075_20210311_20210317_01_T1\LC08_L1TP_223075_20210311_20210317_01_T1_B3.tif")


#copying metadata from original raster
out_meta = rastDat.meta.copy()

#amending original metadata
out_meta.update({'nodata': 0,
                 'height' : out_img.shape[1],
                 'width' : out_img.shape[2],
                 'transform' : out_transform}) 

# writing and then re-reading the output data to see if it looks good
for i in range(out_img.shape[0]):
    with rio.open(rf"C:\Dados_Espaciais\DSM\Bare_Soil_Landsat\Teste_{i+1}_masked.tif",'w',**out_meta) as dst:
        dst.write(out_img[i,:,:],1)

This way you tell the program: Check the areas in BQA with these "Cloud_Values" and exclude these areas, but in the landsat image that I provided.这样您就可以告诉程序:使用这些“Cloud_Values”检查 BQA 中的区域并排除这些区域,但在我提供的陆地卫星图像中。 I hope it works.我希望它有效。

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

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