I assumed oiio.FLOAT describes the data type and that script wouldn't know
whether the texture it was reading was UINT8 linear, gamma22, or sRGB.

That assumption seems to be correct. I changed the script to UINT8 and I'm
still getting basically the same result. Black is 0 and white is 255 but
50% gray should be higher than 128 due to the nonlinear sRGB LUT:

$ python ~/scripts-dev/miplevels.py checker_uint8_sRGB.tx
> 0 512x512=262144 min=0 med=255 max=255
> 1 256x256=65536 min=0 med=255 max=255
> 2 128x128=16384 min=0 med=255 max=255
> 3 64x64=4096 min=0 med=255 max=255
> 4 32x32=1024 min=127 med=127 max=155
> 5 16x16=256 min=127 med=127 max=142
> 6 8x8=64 min=127 med=127 max=135
> 7 4x4=16 min=127 med=129 max=131
> 8 2x2=4 min=128 med=129 max=129
> 9 1x1=1 min=129 med=129 max=129
>

As a sanity check I made a uniform 50% grey texture and the values are at
188, consistent with sRGB 50% grey:

$ iinfo --stats grey_float32_lin.tif
> grey_float32_lin.tif :  512 x  512, 3 channel, float tiff
>     Stats Min: 0.500000 0.500000 0.500000 (float)
>     Stats Max: 0.500000 0.500000 0.500000 (float)
>     Stats Avg: 0.500000 0.500000 0.500000 (float)
>     Stats StdDev: 0.000000 0.000000 0.000000 (float)
>     Stats NanCount: 0 0 0
>     Stats InfCount: 0 0 0
>     Stats FiniteCount: 262144 262144 262144
>     Constant: Yes
>     Constant Color: 0.500000 0.500000 0.500000 (float)
>     Monochrome: Yes
>

$ maketx --oiio -d uint8 --unpremult --colorconvert linear sRGB
> grey_float32_lin.tif -o grey_uint8_sRGB.tx
>


$ python ~/scripts-dev/miplevels.py grey_uint8_sRGB.tx
> 0 512x512=262144 min=188 med=188 max=188
> 1 256x256=65536 min=188 med=188 max=188
> 2 128x128=16384 min=188 med=188 max=188
> 3 64x64=4096 min=188 med=188 max=188
> 4 32x32=1024 min=188 med=188 max=188
> 5 16x16=256 min=188 med=188 max=188
> 6 8x8=64 min=188 med=188 max=188
> 7 4x4=16 min=188 med=188 max=188
> 8 2x2=4 min=188 med=188 max=188
> 9 1x1=1 min=188 med=188 max=188


On Sun, 10 Jan 2021 at 18:48, Solomon Boulos <bou...@cs.stanford.edu> wrote:

> Doesn’t get as float convert from sRGB to Linear in your miplevels.py? If
> you don’t want conversion, open it as int8.
>
> On Sun, Jan 10, 2021 at 10:39 Søren Ragsdale <sor...@gmail.com> wrote:
>
>> I have "checker_float32_lin.tif", a simple RGBA black and white
>> checkerboard. Each black or white square is 8 pixels wide, and every pixel
>> value is either 0.0 or 1.0.
>>
>> I'm using OIIO to turn this float32 scene-linear TIFF into a uint8 sRGB
>> albedo texture:
>>
>> maketx --oiio -d uint8 --unpremult --colorconvert linear sRGB
>> checker_float32_lin.tif -o checker_uint8_sRGB.tx
>>
>> I've written miplevels.py (see attached) which prints the min, median,
>> and max values of the first color channel for each mipmap level of the
>> texture. Here's the output:
>>
>> $ python ~/scripts-dev/miplevels.py checker_uint8_sRGB.tx
>>> 0 512x512=262144 min=0.0 med=1.0 max=1.0
>>> 1 256x256=65536 min=0.0 med=1.0 max=1.0
>>> 2 128x128=16384 min=0.0 med=1.0 max=1.0
>>> 3 64x64=4096 min=0.0 med=1.0 max=1.0
>>> 4 32x32=1024 min=0.498039245605 med=0.498039245605 max=0.607843160629
>>> 5 16x16=256 min=0.498039245605 med=0.498039245605 max=0.556862771511
>>> 6 8x8=64 min=0.498039245605 med=0.498039245605 max=0.529411792755
>>> 7 4x4=16 min=0.498039245605 med=0.505882382393 max=0.51372551918
>>> 8 2x2=4 min=0.501960813999 med=0.505882382393 max=0.505882382393
>>> 9 1x1=1 min=0.505882382393 med=0.505882382393 max=0.505882382393
>>
>>
>> As the mipmaps decrease in size the median value converges on 0.5. Except
>> this is a sRGB texture. The value for 50% grey should be around 0.737 in
>> sRGB space.
>>
>> It appears maketx is converting the values from linear to sRGB then
>> scaling to create the mipmaps. When the source and destination color space
>> are specified I think maketx should scale in scene linear color space,
>> *then* convert to sRGB before saving each mipmap.
>>
>> Is this a bug? Is there a flag or workaround that I should know about?
>>
>>
>> https://paroj.github.io/gltut/Texturing/Tut16%20Mipmaps%20and%20Linearity.html
>> _______________________________________________
>> Oiio-dev mailing list
>> Oiio-dev@lists.openimageio.org
>> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>>
> _______________________________________________
> Oiio-dev mailing list
> Oiio-dev@lists.openimageio.org
> http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org
>
import sys
import OpenImageIO as oiio
import numpy as np


def miplevels(fpath):
    b_all = oiio.ImageBuf(fpath)
    for miplevel in range(0, b_all.nmiplevels):
        # open the mipmap level
        b = oiio.ImageBuf(fpath, 0, miplevel)
        # get all the pixels
        pixels = b.get_pixels(oiio.UINT8)
        # slice pixels from the first channel
        pixels = pixels[::b.nchannels]
        # sort pixel values
        pixels = np.sort(pixels)
        print "{0} {1}x{2}={3} min={4} med={5} max={6}".format(
              miplevel,
              b.ymax - b.ymin + 1,
              b.xmax - b.xmin + 1,
              len(pixels),
              pixels[0],
              pixels[len(pixels) / 2],
              pixels[-1])

if __name__ == "__main__":
    miplevels(sys.argv[1])
_______________________________________________
Oiio-dev mailing list
Oiio-dev@lists.openimageio.org
http://lists.openimageio.org/listinfo.cgi/oiio-dev-openimageio.org

Reply via email to