Потеря данных изображения при конвертации float32 в ushort - PullRequest
0 голосов
/ 08 марта 2020

Я пытаюсь просмотреть 16-битный пиксельный массив из UE4 в OpenCV. Каждый пиксель имеет тип FFloat16Color и имеет 4 переменные (RGBA) типа FFloat, FFloat имеет две соответствующие части: Encoded (возвращает переменную uint16) и функцию GetFloat() (возвращает a float32)

Используя одну из этих переменных, я смогу создать копию изображения в OpenCV, хотя в настоящее время вывод OpenCV возвращает затемненное изображение .

Используя значение с плавающей точкой, я попытался умножить на 65535, 65504 и 32768 следующим образом:

PixelVal = (ushort)(floatval*multiplier)

Используя версию encoded, я получаю "молочное" изображение

Переменная encoded рассчитывается так (я думаю):

FORCEINLINE void FFloat16::Set(float FP32Value)
{
    FFloat32 FP32(FP32Value);

    // Copy sign-bit
    Components.Sign = FP32.Components.Sign;

    // Check for zero, denormal or too small value.
    if (FP32.Components.Exponent <= 112)            // Too small exponent? (0+127-15)
    {
        // Set to 0.
        Components.Exponent = 0;
        Components.Mantissa = 0;

         // Exponent unbias the single, then bias the halfp
         const int32 NewExp = FP32.Components.Exponent - 127 + 15;

         if ( (14 - NewExp) <= 24 ) // Mantissa might be non-zero
         {
             uint32 Mantissa = FP32.Components.Mantissa | 0x800000; // Hidden 1 bit
             Components.Mantissa = Mantissa >> (14 - NewExp);
             // Check for rounding
             if ( (Mantissa >> (13 - NewExp)) & 1 )
             {
                 Encoded++; // Round, might overflow into exp bit, but this is OK
             }
         }
    }
    // Check for INF or NaN, or too high value
    else if (FP32.Components.Exponent >= 143)       // Too large exponent? (31+127-15)
    {
        // Set to 65504.0 (max value)
        Components.Exponent = 30;
        Components.Mantissa = 1023;
    }
    // Handle normal number.
    else
    {
        Components.Exponent = int32(FP32.Components.Exponent) - 127 + 15;
        Components.Mantissa = uint16(FP32.Components.Mantissa >> 13);
    }
}

Чего мне здесь не хватает? Что заставляет гистограмму действовать так?

...