Причина такого мозаичного вида заключается в том, что каждое отдельное изображение рисуется с серой шкалой, растянутой от минимального к максимальному изображению, а НЕ по всему минимальному / максимальному. Когда вы объединяете все изображения в одно, ну, есть только один мин / макс. То же самое верно и для VRT, поскольку VRT рассматривает все изображения как одно (когда вы посмотрите в файл VRT, вы увидите общую статистику).
Когда оба, слияние и VRT, не являются опцией, следующий скрипт может помочь.
В первом цикле я перебираю все слои, выбирая растры и получаю оценку их минимального / максимального интервала. Так работает сама QGIS. Из этих значений min / max я вычисляю глобальные min / max
Во втором цикле средства визуализации для всех растровых слоев настраиваются таким образом, чтобы серая шкала растягивалась через глобальный интервал мин / макс.
gmin = 9999
gmax = -9999
layers = []
# loop over all layers, take rasters and estimate min, max values
for layer in iface.mapCanvas().layers():
if isinstance(layer, QgsRasterLayer):
# change percentages and sample size to increase or decrease accuracy
min_max = layer.dataProvider().cumulativeCut(1, 0.02, 0.98, theSampleSize=250000)
gmin = min(gmin, min_max[0])
gmax = max(gmax, min_max[1])
layers.append(layer)
# for all rasters create a single band gray scale renderer with
# gray scale stretched across the interval [gmin..gmax]
for rasterlayer in layers:
renderer = QgsSingleBandGrayRenderer(rasterlayer.dataProvider(), 1)
# take the first band (0)
ce = QgsContrastEnhancement(rasterlayer.dataProvider().dataType(0))
ce.setContrastEnhancementAlgorithm(QgsContrastEnhancement.StretchToMinimumMaximum)
ce.setMinimumValue(gmin)
ce.setMaximumValue(gmax)
renderer.setContrastEnhancement(ce)
rasterlayer.setRenderer(renderer)
# refresh canvas to show changes
iface.mapCanvas().refresh()