Экспорт массива карты высот в 16-битное сырье - PullRequest
0 голосов
/ 01 ноября 2018

У меня есть массив 256x256 float s, который представляет карту высот. Я хотел бы экспортировать его в 16-битное изображение в формате RAW. Каков будет правильный способ конвертации float в uint16_t. ( Я знаю о потере точности )

Мой быстрый и грязный код для тестирования:

void ExportHeightmap(const Vector<float>& rHeights)
{
    std::vector<uint16_t> output(256 * 256);

    float min = std::numeric_limits<float>::max();
    float max = std::numeric_limits<float>::min();

    for (size_t i = 0; i < output.size(); ++i)
    {
        float f = rHeights[i];

        if (min > f) min = f;
        if (max < f) max = f;

        output[i] = static_cast<uint16_t>(rHeights[i]);
    }

    std::cout << " Min: " << min << std::endl; // -49.77
    std::cout << " Max: " << max << std::endl; // 357.84

    std::fstream file("Heightmap.raw", std::ios::out | std::ios::binary);
    file.write((char*)output.data(), output.size() * sizeof(uint16_t));
}

РЕДАКТИРОВАТЬ: моя цель - экспортировать карту высот, сделанную в приложении, в изображение.

1 Ответ

0 голосов
/ 01 ноября 2018

Полагаю, OP хочет использовать весь диапазон uint16_t, т.е. 0 ... 65535.

В этом случае значения высоты должны быть смещены и масштабированы до нового диапазона, то есть масштаб (макс. - мин.) -> 65535, и перевод мин. -> 0.

Это может выглядеть так:

        value - min
pixel = ----------- * 65535
         max - min

В коде:

#include <cstdint>
#include <iomanip>
#include <iostream>

std::uint16_t floatToUInt16(float value, float min, float max)
{
  return (std::uint16_t)((value - min) / (max - min) * 65535.0f);
}

int main()
{
  float min = -49.77f, max = 357.84f;
  // some test values
  float values[] = { 0.0f, min, max, min / 2, max / 2 };
  // test conversion
  for (float value : values) {
    std::cout << std::fixed << std::setw(10) << value
      << " -> "
      << std::setw(5) << floatToUInt16(value, min, max)
      << '\n';
  }
  return 0;
}

Выход:

  0.000000 ->  8001
-49.770000 ->     0
357.839996 -> 65535
-24.885000 ->  4000
178.919998 -> 36768

Живая демоверсия на coliru

Если бы это было сделано в цикле, я бы немного его оптимизировал. Следовательно, 66535.0f / (max - min) - это фиксированный коэффициент, применяемый ко всем значениям высоты. Так что стоит посчитать этот коэффициент перед входом в цикл.

...