I am trying to access individual pixel values in a raster layer I'm working with. I can use QgsRasterBandStats to get some information about the raster layer with the following code:
layer = iface.activeLayer()
print("Active Layer: ", layer.name())
provider = layer.dataProvider()
extent = layer.extent()
stats = provider.bandStatistics(1, QgsRasterBandStats.All)
print("min value =", stats.minimumValue)
print("max value =", stats.maximumValue)
I'm using the minimumValue and maximumValue attributes of QgsRasterBandStats. All the attributes are listed in the documentation.
In this raster layer I'm working with, there are really only 7 raster values. If I go into the symbology and manually classify these values, you can see them below.
What I'd really like to do is capture these values in a list, for example. Is there a way to access the individual pixel values in a raster object using QgsRasterBandStats?
Or could I choose a raster value (155 for example) and print the number of pixels with that value? Using something like the following pseudocode?
desired_value = 155
print(count of pixels with desired_value)
Answer
You can do that by using 'block' method from QgsRasterDataProvider for accessing the individual pixel values in a raster object. Below code adds necessary lines to your code for producing each desired counts.
layer = iface.activeLayer()
print("Active Layer: ", layer.name())
provider = layer.dataProvider()
extent = layer.extent()
stats = provider.bandStatistics(1, QgsRasterBandStats.All)
print("min value =", stats.minimumValue)
print("max value =", stats.maximumValue)
provider = layer.dataProvider()
extent = provider.extent()
rows = layer.height()
cols = layer.width()
block = provider.block(1, extent, cols, rows)
values = [ [] for i in range(rows) ]
for i in range(rows):
for j in range(cols):
values[i].append(block.value(i,j))
flattened_list = [ element for list in values for element in list ]
unique = [ flattened_list[i] for i in range(len(flattened_list)) if flattened_list[i] not in flattened_list[:i] ]
for item in unique:
count = 0
for element in flattened_list:
if element == item:
count += 1
print ("value: ", item, "count: ", count)
I tried above code out with a random raster with only ten values (between 1 and 10) and result, printed at Python Console, it was as follow:
Active Layer: random_raster
min value = 1.0
max value = 10.0
value: 8.0 count: 38
value: 2.0 count: 51
value: 3.0 count: 34
value: 6.0 count: 43
value: 9.0 count: 33
value: 1.0 count: 43
value: 5.0 count: 38
value: 7.0 count: 39
value: 4.0 count: 41
value: 10.0 count: 40
No comments:
Post a Comment