Как конвертировать float16 в uint8 в Python для файлов EXR - PullRequest
0 голосов
/ 14 мая 2018

Я использую OpenEXR для чтения файлов EXR в Python. У меня есть R, G и B каналы с половиной данных (float16). Используя Numpy, я безуспешно пытался преобразовать данные из float16 в uint8 (0-255 цветов).

        rCh = getChanEXR(imageFile, 'R','HALF')
        rCh = np.array(rCh).astype('uint8')

Итак, я поместил значения пикселей R-канала в переменную rCh. Затем я преобразовываю array.array в np.array, чтобы я мог использовать метод astype для преобразования его в uint8. Я новичок в этом, поэтому у меня явно нет прав, поскольку все значения становятся равными 0. Первоначально значения были такими: 0.0, 2.9567511226945634e-14, 1.2295237050707897e-10 и т. Д.

В дополнение к значениям float16 у меня также есть некоторые регулярные значения с плавающей точкой, которые необходимо нормализовать. Я думаю, что мне нужно нормализовать значения float16, прежде чем они могут быть установлены в диапазоне от 0 до 255.

Есть идеи? Спасибо.

Добавление кода для def, упомянутого здесь getChanEXR (просто пользовательская def, основанная на коде из документации по Python OpenEXR для получения данных канала.

def getChanEXR(curEXRStr, curChannel, dataType):
    #import OpenEXR, Imath, array
    pt = 'none'
    if dataType == 'HALF':
        pt = Imath.PixelType(Imath.PixelType.HALF)
    if dataType == 'FLOAT':
        pt = Imath.PixelType(Imath.PixelType.FLOAT)
    if dataType == 'UINT':
        pt = Imath.PixelType(Imath.PixelType.UINT)
    chanstr = OpenEXR.InputFile(curEXRStr).channel(curChannel, pt)
    chan = array.array('f', chanstr)
    return chan

1 Ответ

0 голосов
/ 14 мая 2018

У меня нет большого опыта работы с array.array, но я верю, что вы можете преобразовать его в массив с плавающей точкой, так что с ним немного проще работать:

rCh = np.asarray(rCh, dtype=np.float)

Если ваши данные нормализованы в [0,1], умножьте их на 255 до преобразования:

rCh = np.asarray(rCh * 255, dtype=np.uint8)

Я полагаю, что это сокращает дробную часть. Ручное округление должно быть безопаснее? (не уверен, см. Обсуждение в комментариях, я думаю, что правильный подход здесь будет размытым, но я думаю, что этот вопрос заслуживает лучшего изучения относительно вашего конкретного варианта использования)

rCh = np.asarray(np.around(rCh * 255), dtype=np.uint8)

Если он не нормализован, вы можете просто сделать

rCh -= rCh.min()
rCh /= rCh.max()

А затем преобразовать его в 8 бит

rCh = np.asarray(rCh * 255, dtype=np.uint8)
...