如何对每个像素应用电影色调映射

时间:2018-07-29 07:03:25

标签: vb.net graphics

我不会尝试完全理解所有这些内容,但是我想知道如何将电影色调映射的公式应用于我输入的图像的像素,最后输出色调映射的图像,以编程方式。

现在,对于每个像素的RGB,我已经了解了

Function f(x) 
  return x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F)) - E/F
End Function

'code for reading bitmap I want to affect, pixel by pixel, and looping the below:

For each pixel
 Dim new_r = f(orig_r)/f(W)
 Dim new_g = f(orig_g)/f(W)
 Dim new_b = f(orig_b)/f(W)
'code to write pixel to newly forming bitmap
Next

'code to save and display bitmap

但是,这不起作用,因为f(r / g / b)/ f(W)是非常接近1的数字,而不是有意义的RGB 0-255值,所以显然我不是得到这个。

我还没有^ 0.45或类似的东西-不知道我是否应该,或者在什么时候。

我用VB.NET编写代码,所有这些示例都用C编写,我只是不了解,所以我将非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

大多数色调映射公式都适用于0到1之间的线性颜色值。因此,只需将RGB值转换为两倍并除以255,即可达到此范围,进行色调映射,然后将结果相乘乘以255再回到原始范围。

Dim origRNormalized = CDbl(orig_r) / 255.0
'...
Dim new_r = Math.Round(f(origRNormalized)/f(W) * 255.0)
'...
'Make sure that the values are still in the 0-255 range

请注意,由于颜色分辨率已经很低,这可能会将色彩伪像引入8位图像。

^0.45^(1 / 2.2)是所谓的伽马校正。它旨在抵消屏幕自己进行的颜色映射。如果您保存为经过伽玛校正的文件格式(大多数是这种格式),则需要执行此操作。使用Double范围内的0-1值而不是量化值来执行此操作。而且,如果您的输入已经是经过伽马校正的图像,则需要在开始时进行前向变换(^2.2)。