I'm trying to implement a custom contrast enhancement function that will allow me to enhance an active raster layer in QGIS without having to create a new raster file.
I'm not trying to do a MinMaxEnhancement or use any of the other existing enhancement methods, I'd like to use a custom function that uses mean statistics as well as min, max.
This is my code so far (I'm doing this within a plugin btw):
layer = self.iface.activeLayer()
provider = layer.dataProvider()
renderer = layer.renderer()
for band_no in range(1, 4):
stats = provider.bandStatistics(band_no, stats=QgsRasterBandStats.All, sampleSize=0)
band_type = renderer.dataType(band_no)
enhancement = QgsContrastEnhancement(band_type)
enhancement.setContrastEnhancementAlgorithm(QgsContrastEnhancement.UserDefinedEnhancement)
function = CustomFunction(band_type, stats.minimumValue, stats.maximumValue, stats.mean)
enhancement.setContrastEnhancementFunction(function)
value = enhancement.enhanceContrast(20)
self.iface.messageBar().pushMessage("Success", f'band: {band_no} value: {value}', level=Qgis.Success, duration=3)
if band_no == 1:
renderer.setRedContrastEnhancement(enhancement)
elif band_no == 2:
renderer.setGreenContrastEnhancement(enhancement)
else:
renderer.setBlueContrastEnhancement(enhancement)
layer.triggerRepaint()
And my CustomFunction (I'm returning a fixed value 50
for testing purposes, in future I plan to replace this with a function that uses min, max and mean stats from each raster band):
class CustomFunction(QgsContrastEnhancementFunction):
def __init__(self, data_type, min_value: float, max_value: float, mean: float):
super().__init__(data_type, min_value, max_value)
self.mean = mean
self.setMinimumValue(min_value)
self.setMaximumValue(max_value)
def enhance(self, value: float) -> int:
return 50
The value returned by enhanceContrast(20)
is 50
as expected. However, the layer vanishes as if it had been turned off, I'd have expected the layer to have a flat colour with a value of 50 for each pixel.
To be honest I can't find any examples or much documentation on the setContrastEnhancementFunction
method, so I could be using it incorrectly.