Преобразование спутниковых фотографий Земли в текстурные карты на сфере (OpenGL ES)
У нас есть 5 геостационарных спутников, расположенных вокруг экватора (не на равном расстоянии, но почти), которые каждый день фотографируют Землю. Выход каждой фотографии - сюрприз! - фотография сферы, сделанная с большого расстояния.
Мне нужно собрать эти фотографии в единую текстурную сферу, и я не знаю, как лучше это сделать. Ключевые проблемы:- фотографии-очевидно-сильно искажаются, чем дальше вы идете от центра, так как они смотрят на сфера Существует много сотен "наборов" из 5 фотографий, сделанных в разное время суток. Любое решение должно быть программным - я не могу просто сделать это вручную : ( Выходной платформой является iPad3: Open GL ES 2, текстуры до 4096x4096-но не такие мощные, как настольный графический процессор. Я не очень хорошо разбираюсь в шейдерах (хотя я сделал много предварительных шейдеров OpenGL) Сами фотографии имеют высокое разрешение, и я не уверен, что смогу загрузить все 5 текстур одновременно. У меня также есть очень текстура высокого разрешения загружена для поверхности планеты (под фотографиями со спутника).
У меня уже есть: одна прямоугольная текстура, отображенная на сферу (моя сфера-это стандартная сетка, обернутая в сферу, с вершинами, равномерно распределенными по поверхности), так что ... Я попытался преобразовать 5 фотографий сфер в единую прямоугольную карту (но пока безуспешно; хотя кто-то указал мне на "полярную деформацию греха", которая, похоже, могла бы работать лучше).
Я тоже думал о том, чтобы сделать что-то забавное с созданием кубической карты из 5 фотографий и умно решить, какую из фотографий читать для данного пикселя, но я не совсем уверен.
Есть ли лучший способ? Что-то я упустил из виду? Или у кого-то есть конкретный способ достижения всего этого?
1 ответ:
Я бы сделал из него прямоугольную текстуру.
Вам понадобится 2 x 2D текстуры/массивы один для
r,g,b
суммирования цветов avg и один для count cnt. Также я не уверен, что буду использоватьOpenGL/GLSL для этого мне кажется, что C/C++ будет лучше для этого.Я бы сделал это так:
- очистите текстуру назначения (
avg[][]=0, cnt[][]=0
)Получить спутник положение / направление, время
Из положения и направления создают матрицу преобразования, которая проецирует Землю теми же способами, что и на фото. Затем от времени определяют сдвиг вращения.
Сделайте петлю через всю поверхность Земли
Всего две вложенные петли
a
- вращение и `b - расстояние от экватора.Получить
x,y,z
изa,b
и преобразовать матрицу + сдвиг вращения (a
-ось)Также может сделать это задом наперед Но это сложнее, но быстрее и точнее. Вы также можете интерполировать
x,y,z
между соседними(pixels/areas)[a][b]
Добавить пиксель
Если
x,y,z
находится на лицевой стороне (z>0
илиz<0
зависит от направления камерыZ
), тоavg[a][b]+=image[x][y]; cnt[a][b]++;
Конец вложенного цикла из точки #3.
- Гото #2 со следующей фотографией
Сделайте цикл через всю текстуру
avg
, чтобы восстановить среднее значение цветif (cnt[a][b]) avg[a][b]/=cnt[a][b];
[Примечания]
Можно проверить, является ли скопированный пиксель:
Полученные в течение дня или ночи (используйте только то, что вы хотите, а не смешивать оба вместе!!!) также может определять облака (я думаю, что серый/белый-это цвета, а не снег) и игнорировать их.
Не переполняйте цвета
Может использовать 3 отдельные текстуры
r[][],g[][],b[][]
вместоavg
, чтобы избежать этогоМожет игнорируйте области вблизи краев земли, чтобы избежать искажений
Может применять поправки освещения
Из координат
time
иa,b
для нормализации освещенностиНадеюсь, что это помогает ...
[Edit1] ортогональная проекция
Итак, ясно, что я имею в виду под ортогональной проекцией:
Это используемая текстура (не могу найти ничего лучше подходящего и бесплатного в интернете) и хотел бы используйте реальный спутниковый снимок, а не какой-то рендеринг ...
Это мое приложение для ортогональной проекции
Красные,зеленые, синие линии - это земная система координат (ось
x,y,z
)- линии (красный,зеленый,синий)-белый-это система координат спутниковой проекции (ось
x,y,z
)Суть в том, чтобы преобразовать координаты земной вершины
(vx,vy,vz)
в координаты спутника(x,y,z)
, еслиz >= 0
тогда его допустимая вершина для обработанной текстуры, поэтому вычислите текстуру координаты непосредственно изx,y
без перспективы (ортогонально).Например
tx=0.5*(+x+1);
... еслиx
был масштабирован до<-1,+1>
и используемая текстураtx <0,1>
то же самое относится к осиy
:ty=0.5*(-y+1);
... еслиy
был масштабирован до<-1,+1>
и используемая текстураty <0,1>
(моя камера имеет перевернутую систему координатy
, соответствующую матрице текстуры, поэтому перевернутый знак на осиy
)Если
z < 0
, то вы обрабатываете вершину вне диапазона текстур, поэтому игнорируйте ее ... как ты можно видеть на изображении, что внешние границы текстуры искажены, поэтому вы должны использовать только внутреннюю часть (например, 70% площади изображения Земли), также вы можете сделать некоторую коррекцию координат текстуры, зависящую от расстояния от средней точки текстуры. Когда вы это сделаете, то просто объедините все проекции спутниковых изображений в одно изображение, и это все.[Edit2] Ну я немного поиграл с ним и обнаружил следующее:
- коррекция обратной проекции не требуется. работа для моей текстуры вообще я думаю, что возможно это пост обработанное изображение ...
Коррекция средней точки на основе расстояния кажется хорошей, но используемый масштабный коэффициент нечетен, не знаю, зачем умножать на 6, когда он должен быть 4, я думаю ...
tx=0.5*(+(asin(x)*6.0/M_PI)+1); ty=0.5*(-(asin(y)*6.0/M_PI)+1);
- скорректированная нелинейная проекция (по asin)
- скорректированный нелинейный проекционный краевой зум
- искажений очень много меньше, чем без
asin
коррекции координат текстуры