gdal. пакетное сохранение каналов растра

Не знаете, где задать вопрос? Задавайте здесь.
Ответить
Аватара пользователя
soov
Новоприбывший
Сообщения: 11
Зарегистрирован: 17 мар 2018, 11:40
Репутация: 1
Откуда: Санкт-Петербург

gdal. пакетное сохранение каналов растра

Сообщение soov » 05 июн 2018, 17:18

Здравствуйте. Помогите, пожалуйста.
У меня следующая задача: Есть много растров. Много! Из них нужно вытащить один канал (первый) и соответственно сохранить. Я понимаю, как это сделать по одному снимку используя gdal.
gdalBand = gdalData.GetRasterBand( 1 )
Далее Create()
Но это дико медленно. В итоге перешёл на scanex. Но всё же, понимаю, что это не должно быть сложно... в gdal всё это сделать...
Я пытаюсь создать список растров в txt. Считываю его python' ом, но у меня ничего не выходит. :cry:
f = open("list.txt",'r')
image_list = f.read()
открываю
gdal'ом
gdalData = gdal.Open( image_list)
А так оно вообще можно? и куда двигаться? Или это вообще в другую сторону.
Я с языком сильно на вы. Задача ключевая, по форуму искал, но не нашёл, та бы тему конечно же не множил. Помогите, товарищи, строчкой кода. :idea:

Александр Мурый
Гуру
Сообщения: 5123
Зарегистрирован: 26 сен 2009, 16:26
Статьи: 3
Проекты: 5/1
Репутация: 753
Ваше звание: званий не имею
Откуда: Москва

Re: gdal. пакетное сохранение каналов растра

Сообщение Александр Мурый » 05 июн 2018, 17:28

Я бы использовал простой цикл на Питоне или шелле (зависит от ОС) с утилитой <gdal_translate> c параметром "-b 1" для каждого растра.
Пример на шелле:

Код: Выделить всё

for rast in *.tif; do
   gdal_translate -b 1 $rast $(basename $rast .tif)_b1.tif
done
В случае Питона и GDAL >=2.1 можно ещё так:
https://gis.stackexchange.com/a/237411
Редактор материалов, модератор форума

Аватара пользователя
soov
Новоприбывший
Сообщения: 11
Зарегистрирован: 17 мар 2018, 11:40
Репутация: 1
Откуда: Санкт-Петербург

Re: gdal. пакетное сохранение каналов растра

Сообщение soov » 08 июн 2018, 09:57

Александр Мурый, это ок, спасибо. "gdal_translate> c параметром "-b 1" для каждого растра."

Но не подскажите как мне перебрать все растры типа *.tiff, в папке и соответственно и чтобы он сохранял типа в другую директорию, с доп. буквой новой в названии растра или типа того. Стандартным циклом у меня не получается, я так понимаю, gdal должен каждый растр открыть. Или не так?
По subprocess вообще не понял, к чему это.

nickleb
Гуру
Сообщения: 835
Зарегистрирован: 22 май 2010, 20:20
Репутация: 92

Re: gdal. пакетное сохранение каналов растра

Сообщение nickleb » 10 июн 2018, 07:59

В R вашу задачу через библиотеку "raster" можно решить
"многострочно-пошагово" через процедурный for-цикл
(без семейства директив apply и map функциональной парадигмы, которая, конечно, в R славная-таки доминанта - но так "привычно-понятней" и детализировать, и комментировать можно каждый
"шажок"):

Код: Выделить всё

#Подключаем библиотеку "raster"
library("raster")
#Папка с исходными
InputDir <- file.path("C:", "Input")
#Папка с записываемыми
OutputDir <- file.path("C:", "Output")
#Получаем список исходных
ListInput <- list.files(InputDir, full.names = TRUE)
#Сколько всего исходных
nFiles <- length(ListInput)
#Цикл по списку исходных
for ( i in seq_along(ListInput) ) {
         #Имя текущего файла
	 NameInputRstr <-  ListInput [ i ]
	 #Короткое имя текущего файла
         BaseName <- basename( NameInputRstr )
	 #Читаем исходный
         CurrentBrickRstr <- raster::brick( NameInputRstr )
	 #Извлекаем первый band
	 BandFirst <- CurrentBrickRstr [[ 1 ]]
	 #Генерируем короткое имя выходного
         NameOutputBand <-  paste0( "FirstBand_",  BaseName)
	 #Полное имя выходного
         PathNameOutputRstr <-  file.path( OutputDir, NameOutputBand )
	 #Пишем первый band в файл
         writeRaster(BandFirst, PathNameOutputRstr, format="GTiff", overwrite=TRUE)
	 #Удаляем из памяти то, с чем отработали
	 rm(CurrentBrickRstr)
	 rm(BandFirst)
	 #Информационная строка о ходе работы (базовые имена входного, выходного, какой по счёту файл...)
	 StringPrint <- paste0( BaseName, " ==> ", NameOutputBand, " Counter: ", as.character(i), " from ", as.character(nFiles) )
	 #Печать информационной строки
	 print( StringPrint )
}
Если есть коллеги у вас, которые c R работали, - то помогут его поставить за минут 10-15-ть...
Нет таковых ребят рядом - та и сами можете по-Google'ить и за полчасика-академический чвс справиться... Успеха, Удачи!

Игорь Белов
Гуру
Сообщения: 1600
Зарегистрирован: 04 янв 2011, 22:00
Статьи: 12
Проекты: 1
Репутация: 996
Откуда: Казань

Re: gdal. пакетное сохранение каналов растра

Сообщение Игорь Белов » 10 июн 2018, 12:30

soov писал(а):
08 июн 2018, 09:57
не подскажите как мне перебрать все растры типа *.tiff, в папке и соответственно и чтобы он сохранял типа в другую директорию, с доп. буквой новой в названии растра или типа того
Александр уже практически ответил на этот вопрос. Добавьте путь к выходным файлам в bash-скрипте:

Код: Выделить всё

for rast in *.tif
do
    gdal_translate -b 1 $rast другая_директория/${rast%.*}_b1.tif
done
Можете заменить "_b1" на свою доп. букву.

Получить эмулятор терминала UNIX под Windows очень просто:
[Старт] → [QGIS] → [Setup] и добавить модуль msys.

Boris
Гуру
Сообщения: 4086
Зарегистрирован: 10 апр 2006, 22:34
Статьи: 3
Проекты: 1
Репутация: 398
Откуда: Париж

Re: gdal. пакетное сохранение каналов растра

Сообщение Boris » 10 июн 2018, 21:49

А чем плох встроенный в CMD (Windows XP - 10) оператор FOR?
Они, конечно не так крут как bash, но такую незамысловатую работу как перебор файлов, делает превосходно:

Код: Выделить всё

for %b in ("исходная_директория\*.tif") do gdal_translate -b 1 "%~fb" "другая_директория\%~nb_b1.%~xb"

Аватара пользователя
soov
Новоприбывший
Сообщения: 11
Зарегистрирован: 17 мар 2018, 11:40
Репутация: 1
Откуда: Санкт-Петербург

Re: gdal. пакетное сохранение каналов растра

Сообщение soov » 14 июн 2018, 16:56

Игорь Белов, Большое спасибо, работает и быстро.

Аватара пользователя
soov
Новоприбывший
Сообщения: 11
Зарегистрирован: 17 мар 2018, 11:40
Репутация: 1
Откуда: Санкт-Петербург

Re: gdal. пакетное сохранение каналов растра

Сообщение soov » 14 июн 2018, 17:00

Ещё вопрос, а можно ли таким образом клеить растры, типа один канал с одного, второй и третий канал из другого растра, на выходе получаем типа RGB, экстент у них само-собой идентичный ?

Александр Мурый
Гуру
Сообщения: 5123
Зарегистрирован: 26 сен 2009, 16:26
Статьи: 3
Проекты: 5/1
Репутация: 753
Ваше звание: званий не имею
Откуда: Москва

Re: gdal. пакетное сохранение каналов растра

Сообщение Александр Мурый » 14 июн 2018, 17:48

soov писал(а):
14 июн 2018, 17:00
а можно ли таким образом клеить растры, типа один канал с одного, второй и третий канал из другого растра, на выходе получаем типа RGB
Сначала вытащите все нужные каналы из растров, затем "gdal_merge.py -separate".
https://gis.stackexchange.com/a/267949
Редактор материалов, модератор форума

Boris
Гуру
Сообщения: 4086
Зарегистрирован: 10 апр 2006, 22:34
Статьи: 3
Проекты: 1
Репутация: 398
Откуда: Париж

Re: gdal. пакетное сохранение каналов растра

Сообщение Boris » 14 июн 2018, 19:36

Александр Мурый писал(а):
14 июн 2018, 17:48
Сначала вытащите все нужные каналы из растров, затем "gdal_merge.py -separate".
По моему, формат VRT позволяет виртуально выбирать каналы. И быстрее, и проще оперировать.
Кроме того, если немного полистать документацию, то где там спрятано и как сделать сборный поканальный виртуальный растр (SimpleSource:).
http://www.gdal.org/gdal_vrttut.html
А уже настроенный виртуальный растр можно и сохранить в реальный через gdal_translate.

Игорь Белов
Гуру
Сообщения: 1600
Зарегистрирован: 04 янв 2011, 22:00
Статьи: 12
Проекты: 1
Репутация: 996
Откуда: Казань

Re: gdal. пакетное сохранение каналов растра

Сообщение Игорь Белов » 14 июн 2018, 20:03

gdalbuildvrt
Просто создайте виртуальную мозаику:

Код: Выделить всё

gdalbuildvrt большой_растр.vrt *.tif

Аватара пользователя
soov
Новоприбывший
Сообщения: 11
Зарегистрирован: 17 мар 2018, 11:40
Репутация: 1
Откуда: Санкт-Петербург

Re: gdal. пакетное сохранение каналов растра

Сообщение soov » 15 июн 2018, 14:02

Чуть-чуть по-медленнее, пожалуйста, у меня получается две директории:
в одной папке растры - 1 канал. (NIR)
в другой папке растры - 2 канала.(GB)
я сваливаю всё в одну директорию... виртуальный растр, ок, но мне нужно сохранить исходное количество файлов... (количество растров в NIR или RGB)
gdal_merge тоже ок, - но там, как я, на данный момент, понимаю, надо вручную подставлять растры на вход и выход. количество растров непростительное, да оно так работает, но подставлять вручную приходится
Но быть может, есть какая то подстановка, в msys, файлы же переименовать не проблема.
Извините, за незнание. Помогите, плиз...

Александр Мурый
Гуру
Сообщения: 5123
Зарегистрирован: 26 сен 2009, 16:26
Статьи: 3
Проекты: 5/1
Репутация: 753
Ваше звание: званий не имею
Откуда: Москва

Re: gdal. пакетное сохранение каналов растра

Сообщение Александр Мурый » 15 июн 2018, 21:15

Лучше покажите скриншоты, что и где у вас там лежит. Потому что так непонятно.
И ещё раз просьба внятно объяснить, из каких растров у вас должен получаться трёхканальный растр.
Редактор материалов, модератор форума

Игорь Белов
Гуру
Сообщения: 1600
Зарегистрирован: 04 янв 2011, 22:00
Статьи: 12
Проекты: 1
Репутация: 996
Откуда: Казань

Re: gdal. пакетное сохранение каналов растра

Сообщение Игорь Белов » 16 июн 2018, 09:40

Прям завидую, умеют же люди задавать абстрактные вопросы, таинственно скрывая суть задачи :lol:

Ладно. Предположим, имеются две папки, "nir" с одноканальными растрами и "gb" с двухканальными. Каждому растру из одной папки соответствует растр из другой по имени и геометрии. Нужно создать папку "out" и поместить туда растры с теми же именами из трёх каналов в таком порядке: gb 1, gb 2, nir.

Код: Выделить всё

#!/usr/bin/env bash
mkdir -p out
for p in gb/*.tif
do
    gdal_translate -b 1 ${p} tmp1.tif
    gdal_translate -b 2 ${p} tmp2.tif
    q=$(basename ${p})
    gdalbuildvrt -separate tmp.vrt tmp1.tif tmp2.tif nir/${q}
    gdal_translate tmp.vrt out/${q}
    rm -f tmp*
done

Аватара пользователя
soov
Новоприбывший
Сообщения: 11
Зарегистрирован: 17 мар 2018, 11:40
Репутация: 1
Откуда: Санкт-Петербург

Re: gdal. пакетное сохранение каналов растра

Сообщение soov » 18 июн 2018, 12:09

Задача сводилась к получению растров в False-color (nir, green, blue), и благодаря вам всё отлично работает. :D
Спасибо большое! Вы лучшие! :)

Ответить

Вернуться в «Я новичок!»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 0 гостей