我认为主要问题是动态范围之一,您的算法可能正确,但是您正在处理错误的数据类型。
通过散焦的透镜,原本可以夹住并变成纯白色的点光源会散布在更大的区域上,因此它形成的光盘不那么明亮,因此无法夹住。
这就是为什么您在真实的散景图像中得到那些漂亮的圆圈的原因。如果剪切信号(使其亮度不如正常情况好,然后通过bokeh模拟将其分散开),您会得到一个暗淡的圆圈(或六角形或其他形状),该圆圈不明显,因此看起来不真实。
您在真实图像链中拥有的是:
bokeh (from the lens) -> digitisation (clipping) -> gamma correction & dynamic range compression
你在做什么
sharp image -> digitisation (clipping) -> gamma correction & dynamic range compression -> bokeh simulation
您将无法获得正确的结果,因为您不使用线性数据。
您可以做的是尝试线性化数据,替换因剪切而丢失的任何动态范围,执行bokeh模拟,然后重做非线性操作!
这是一个例子。我从色调映射的HDR图像开始,给出了高度非线性的结果。这是尝试散景模拟的最差图像!
进行标准的卷积运算以模拟散景(使用photoshop的镜头模糊工具)会产生此结果,该结果与您得到的结果非常相似:
为了获得更好的结果,我应用了一条极端曲线来尝试使图像恢复到色调映射之前的大致水平,其中高光比图像的其余部分要亮得多。我使用关卡工具将中心输入向右推很长一段距离,从1.0到大约0.2)。然后,像以前一样,我应用了镜头模糊工具。最后,我在与第一条曲线相反的方向上应用了一条极限曲线。结果虽然离完美还很远,但看起来更像真实的镜头散景:
如果在代码中执行此操作,请尝试求出每个值,然后应用bokeh模拟例程,然后取每个值的立方根。您应该会看到一个改进。可能需要一些调整。
tl; dr即使已实现了bokeh的理想数学模型,也必须将其应用于未剪切的线性数据。如果对经过大量修改的数据应用相同的计算(即使从数学的角度来看,甚至是对JPEG相机中的标准进行了大量修改),您也会得到截然不同的结果。