Tom94 / tev

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

How the displayed value is calculated? #149

Closed LogWell closed 2 years ago

LogWell commented 2 years ago

I want to analyze an image numerically. The displayed result is different from the output of OpenCV/cvkit.

Take the first-pixel(top-left) value, when check in cvkit with: sv ORTHO_ColorN_01_Z000_PRO.png, and point to the top-left, the result is (126, 131, 254) and is consistent with the first print(). After gammaCorrection and divided by 255, the value is (0.21176471, 0.22745098, 0.98823529), but the displaied value is (0.2086, 0.2270, 0.9911).

Since the image is a normal maps(or in other formats such as depth maps), the accuracy of the values is critical. So we hope tev can add the ability to display raw value.

CODE:

import cv2
import numpy as np

def gammaCorrectionDecoding(src, gamma):
    """
    NOTE: https://stackoverflow.com/a/16521337/10636347
        Gamma decoding is used to restore the original values, so the formula for that is:
        original = ((encoded / 255) ^ gamma) * 255
    """
    table = [((i / 255) ** gamma) * 255 for i in range(256)]
    table = np.array(table, np.uint8)
    return cv2.LUT(src, table)

path_img = "/home/lab9/Videos/for_tev/ORTHO_ColorN_01_Z000_PRO.png"
img = cv2.imread(path_img, -1)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img[1082:1084, 990:993]
print(img)
img = gammaCorrectionDecoding(img, 2.2)
img = img / 255.0
print(img)

RES:

>>> [[[126 131 254]
  [127 131 254]
  [128 131 254]]

 [[123 126 254]
  [123 127 254]
  [122 127 254]]]

>>> [[[0.21176471 0.22745098 0.98823529]
  [0.21568627 0.22745098 0.98823529]
  [0.21568627 0.22745098 0.98823529]]

 [[0.2        0.21176471 0.98823529]
  [0.2        0.21568627 0.98823529]
  [0.19607843 0.21568627 0.98823529]]]

ORTHO_ColorN_01_Z000_PRO tmp

Tom94 commented 2 years ago

Hi there, the displayed value is srgbToLinear(c / 255), where srgbToLinear is the standardized sRGB transform. Image from Wikipedia:

If your PNG has an alpha channel a, then the complete formula is srgbToLinear(c / 255) * a / 255. Note that the alpha multiplication happens after the conversion to linear colors. (This is defined in the PNG specification.)

Cheers!