Tom94 / tev

High dynamic range (HDR) image viewer for graphics people
BSD 3-Clause "New" or "Revised" License
1.02k stars 86 forks source link

gamma correction #150

Closed LogWell closed 2 years ago

LogWell commented 2 years ago

Relate to 149

I think gamma correction is misleading visually and has numerical errors. Right?

    res = 512
    img_ori = np.zeros([res, res, 3]).astype(np.float32)  # RGB
    img_ori[:, :, :2] = 0
    img_ori[:, :, 2] = 1
    img_ori = cv2.cvtColor(img_ori, cv2.COLOR_RGB2BGR)  # BGR

    if True:
        img_nT = (img_ori + 1) / 2
        cv2.imwrite("check_gamma_nT.exr", img_nT)
        print("img_nT:", img_nT[0, 0, :])  # ! print: 1. 0.5 0.5; tev: 0.5000 0.5000 1.0000
        TMP_img_nT = cv2.imread("check_gamma_nT.exr", -1)
        print("TMP_img_nT:", TMP_img_nT[0, 0, :])  # ! print: 1. 0.5 0.5;
        print()
    if True:
        img_nT = (img_ori + 1) / 2
        img_nT = img_nT * 255
        img_nT = img_nT.astype(np.uint8)  # 0.5 ~ 127 ~ 0.4980
        cv2.imwrite("check_gamma_nT.png", img_nT)
        print("img_nT:", img_nT[0, 0, :], img_nT[0, 0, :] / 255)  # ! print: 255 127 127 / 1. 0.4980 0.4980; tev: 0.2122 0.2122 1.0000
        TMP_img_nT = cv2.imread("check_gamma_nT.png", -1)
        print("TMP_img_nT:", TMP_img_nT[0, 0, :], TMP_img_nT[0, 0, :] / 255)  # ! print: 255 127 127 / 1. 0.4980 0.4980;
        print()

check in tev Kazam_screenshot_00001

Kazam_screenshot_00000

check in DaVinci Resolve image

Tom94 commented 2 years ago

The reason that tev prints a different color from the python code is that you're mapping linear colors to bytes and then storing them in a format (.png) that usually stores sRGB colors.

Whenever tev loads a low-dynamic-range image, such as a .png, the colors are transformed to linear space as described in https://github.com/Tom94/tev/issues/149 . This explains how 0.4980 turns into 0.2122.

Whether this is visually misleading is arguable -- it's the standard way to deal with LDR images that have unknown color profiles, but color spaces in general can be a huge mess. I prefer working with raw image formats like .exr for precisely this reason. :)

As for your question about numerical errors: I believe the only significant source of numerical error is the quantization to bytes.

Tom94 commented 2 years ago

One big caveat that I need to mention here: .png allows embedding color profiles, which could in principle work around this issue.

However, the library tev uses to load .png files (STBI) does not support reading of such information. So the best tev can do is guess sRGB. See https://github.com/Tom94/tev/issues/103 for more info