Преобразование спутниковых фотографий Земли в текстурные карты на сфере (OpenGL ES)


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

Мне нужно собрать эти фотографии в единую текстурную сферу, и я не знаю, как лучше это сделать. Ключевые проблемы:
  1. фотографии-очевидно-сильно искажаются, чем дальше вы идете от центра, так как они смотрят на сфера
  2. Существует много сотен "наборов" из 5 фотографий, сделанных в разное время суток. Любое решение должно быть программным - я не могу просто сделать это вручную : ( Выходной платформой является iPad3: Open GL ES 2, текстуры до 4096x4096-но не такие мощные, как настольный графический процессор. Я не очень хорошо разбираюсь в шейдерах (хотя я сделал много предварительных шейдеров OpenGL) Сами фотографии имеют высокое разрешение, и я не уверен, что смогу загрузить все 5 текстур одновременно. У меня также есть очень текстура высокого разрешения загружена для поверхности планеты (под фотографиями со спутника).

У меня уже есть: одна прямоугольная текстура, отображенная на сферу (моя сфера-это стандартная сетка, обернутая в сферу, с вершинами, равномерно распределенными по поверхности), так что ... Я попытался преобразовать 5 фотографий сфер в единую прямоугольную карту (но пока безуспешно; хотя кто-то указал мне на "полярную деформацию греха", которая, похоже, могла бы работать лучше).

Я тоже думал о том, чтобы сделать что-то забавное с созданием кубической карты из 5 фотографий и умно решить, какую из фотографий читать для данного пикселя, но я не совсем уверен.

Есть ли лучший способ? Что-то я упустил из виду? Или у кого-то есть конкретный способ достижения всего этого?

1 4

1 ответ:

Я бы сделал из него прямоугольную текстуру.

Вам понадобится 2 x 2D текстуры/массивы один для r,g,b суммирования цветов avg и один для count cnt. Также я не уверен, что буду использоватьOpenGL/GLSL для этого мне кажется, что C/C++ будет лучше для этого.

Я бы сделал это так:

  1. очистите текстуру назначения (avg[][]=0, cnt[][]=0)
  2. Получить спутник положение / направление, время

    Из положения и направления создают матрицу преобразования, которая проецирует Землю теми же способами, что и на фото. Затем от времени определяют сдвиг вращения.

  3. Сделайте петлю через всю поверхность Земли

    Всего две вложенные петли a - вращение и `b - расстояние от экватора.

  4. Получить x,y,z из a,b и преобразовать матрицу + сдвиг вращения (a-ось)

    Также может сделать это задом наперед Но это сложнее, но быстрее и точнее. Вы также можете интерполировать x,y,z между соседними (pixels/areas)[a][b]

  5. Добавить пиксель

    Если x,y,z находится на лицевой стороне (z>0 или z<0 зависит от направления камеры Z), то

    avg[a][b]+=image[x][y]; cnt[a][b]++;
    
  6. Конец вложенного цикла из точки #3.

  7. Гото #2 со следующей фотографией
  8. Сделайте цикл через всю текстуру avg, чтобы восстановить среднее значение цвет

    if (cnt[a][b]) avg[a][b]/=cnt[a][b];
    

[Примечания]

  1. Можно проверить, является ли скопированный пиксель:

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

  2. Не переполняйте цвета

    Может использовать 3 отдельные текстуры r[][],g[][],b[][] вместо avg, чтобы избежать этого

  3. Может игнорируйте области вблизи краев земли, чтобы избежать искажений

  4. Может применять поправки освещения

    Из координат time и a,b для нормализации освещенности

Надеюсь, что это помогает ...

[Edit1] ортогональная проекция

Итак, ясно, что я имею в виду под ортогональной проекцией:

Текстура спутниковой фотографии (EUMETSAT)

Это используемая текстура (не могу найти ничего лучше подходящего и бесплатного в интернете) и хотел бы используйте реальный спутниковый снимок, а не какой-то рендеринг ...

ортогональная проекция

Это мое приложение для ортогональной проекции

    Красные,зеленые, синие линии - это земная система координат (ось 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 коррекции координат текстуры