Извлечение RGB из 4-полосного изображения (растерио) - PullRequest
0 голосов
/ 11 октября 2018

Я новичок в python и до сих пор знакомлюсь с его библиотеками, извиняюсь, если это вопрос новичка.Я просто хочу отобразить изображение из 4 полос (R, G, B, NIR).Я хочу удалить NIR и оставить другой 3. Как я могу это сделать?Поскольку растерио возвращает объект, а не изображение, я не могу использовать функцию разделения.

from rasterio.plot import show
from matplotlib import pyplot
dataset = rasterio.open('sample.tif')
show(dataset)

Это, конечно, показывает неверный результат (изображение белого и желтого цвета).

РедактироватьЯ попробовал следующее:

img_combined = cv2.merge((dataset.read(1),dataset.read(2),dataset.read(3)))
%matplotlib qt
plt.imshow(img_combined)
plt.xticks([]), plt.yticks([])
plt.show()

, но оно все еще показывает изображение в желтом и белом цветах.

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

Чтобы отобразить только полосы RGB (не альфа) или какую-либо конкретную полосу, вам нужно использовать метод read вместе с методом show.

import rasterio
from rasterio.plot import show

#to display RGB
dataset = rasterio.open('sample.tif')
show(dataset.read([1,2,3]))

#to display just the red band:
show(dataset.read(1))
0 голосов
/ 19 июля 2019

Порядок полос

Порядок полос имеет значение, и их можно заказать по-разному в зависимости от TIFF.В документации данных должно быть указано, каков порядок полос, и, надеюсь, его можно прочитать из самих данных (мой опыт показывает, что это часто не так).

Сначала вы можете попробовать проверить метки полос (хотя,вы все еще хотите обратиться к документации).

>>>src.descriptions
(None, None, None, None)

Если там ничего не помечено, вам следует обратиться к документации по данным.

Допустим, есть 4 полосы, заказанные как BGRN (какв ближнем инфракрасном диапазоне - ближний ИК-порт);тогда вы захотите первые три полосы, но в обратном порядке.

data = src.read([3,2,1])

Нормализация и типы данных

Если ваши полосы не в порядке RGB, вероятно,что он имеет 16-битный целочисленный тип данных, и вам нужно 8 бит для рисования через imshow (или записи в другую кодировку изображений, например, PNG и JPEG).Сначала нормализуйте данные до 0-255, затем приведите от uint16 к uint8.Обратите внимание, что при этом вы теряете точность, поэтому вы хотите провести анализ исходных данных.

import numpy

def normalize(x, lower, upper):
    """Normalize an array to a given bound interval"""

    x_max = numpy.max(x)
    x_min = numpy.min(x)

    m = (upper - lower) / (x_max - x_min)
    x_norm = (m * (x - x_min)) + lower

    return x_norm

# Normalize each band separately
data_norm = numpy.array([normalize(data[i,:,:], 0, 255) for i in range(data.shape[0])])
data_rgb = data_norm.astype("uint8")

Библиотеки изображений и измерения данных

Если вы используетебиблиотека, отличная от rasterio, например, cv2 или PIL, порядок считывания полос из изображений RGB (A) может отличаться, а также порядок размеров.Если вам нужно изменить порядок размеров для вашего метода построения графика, вы можете сделать следующее

# Make the first (band) dimension the last
plt.imshow(numpy.moveaxis(data, 0, -1))
0 голосов
/ 11 октября 2018

Обычно набор данных - это массив, в котором каждый элемент - это полоса, которую вы ищете.Учитывая ваш код, набор данных [0] является R-диапазоном, набор данных [1] G-диапазоном и т. Д.

Итак,

show(dataset[0])

покажет R-группу.

...