Debug 记录
第二步骤中:做 CCM 时候发现有图像有些地方有异常
找到对应点和正常点,输出 CCM 前后的值
由于 HDR 图片没有工具放大看具体坐标的,所以就转成 PNG 图片。而关键点在于我们并不需要看全部的细节,所以我乘了很大的一个数,转成 8 bit转换后左边完全过曝了,但无所谓,我们只看右边暗处细节,找出不正常的点和附近正常点坐标。
所以这里还是很巧妙的,以后遇到 HDR 图可以就这样,不然真的不好弄,请注意两个坑点:第一不要用 OpenHDR 网页中保存 PNG 的功能,他保存的尺寸不一样!第二不要转成 16 bit,不然在 ImageJ 里面看不清,就老老实实用 8 bit!
结果发现居然又正常了
然后打开图片发现确实一样,这里的思路很清晰:要么求矩阵有问题、要么矩阵乘法有问题。所以这里我就先把矩阵存下来,然后用存下来的矩阵反复求,发现图片不一样,那说明矩阵乘法有问题。
网上求解方案
于是在网上搜 np.dot not precise,果然很轻松搜到了问题,发现改成 np.longdouble 类型就好,搞定。
第二步骤中:做 CCM 后用 OpenHDR 打开发现右边偏紫色
寻找对应异常点和正常点
像上面一样暴力转成 PNG 发现也挺正常,没偏色。这里我就走偏了,以为是 OpenHDR 的问题,弄了半天。。
故技重施,输出对应点和正常点
其实之所以走偏,也是因为我暴力转 PNG 找不到异常点,所以也何谈去输出异常点的值呢。后来是直接用了我自己的第三步骤,也就是把 HDR 进行 Tonemapping 后的 PNG 图片,发现也有偏色,因此很顺利找到了对应点和异常点。
其实回头想想是应该这样的。捋一下逻辑:我认为是 OpenHDR 的问题,那就说明我的 HDR 文件没问题,也就是第二步骤没问题,那就顺利成章就执行第三步骤了呀。真傻。
输出异常点后,发现偏色那里是负数,所以用了两个方法:减最小值、负数置为 0,发现后者更好。
第二步骤中:用最优化 DeltaE 做 CCM 发现很不对
无头苍蝇试验
这里真得批评一下自己,我发现不对就开始乱试,浪费很多时间。下面捋一下,也复盘一下应该 Debug 的逻辑。
查看参考色卡和原图中的色卡
因为 CCM 是用原图色卡和参考色卡比较来做的,所以首先就应该把这两个图片输出。果然,参考色卡明显不对,白色一点也不白。
此时就可以看参考色卡中的代码,至少让色卡的白色变白。而获取参考色卡的代码里是根据 LAB 转 RGB 的,所以我们需要用网上对应的转换器工具进行比较。
这里我就要检讨,我没有先找工具,而是看原理。虽然速度也很快,但这种情况真应该找个正确工具对应着看的!
顺带一提,用的工具是这个,很不错:http://www.brucelindbloom.com/index.html?Eqn_Lab_to_XYZ.html
最后就慢慢顺藤摸瓜,发现是获取参考色卡的代码里面有个地方参考白点写错了,把 D50 写成了 D65... 改完后色卡正常,并且结果和上面的工具输出一致(这里就体现了参考工具的重要性了)
修改后还是有问题
修改后还有问题,此时我不应该去加什么对变量进行限制条件之类的... 而是应该在迭代方法中输出他此时的迭代值和迭代次数,看是不是因为迭代次数不够用、迭代值有没有单调递减这些问题。。
当然这里情有可原,我是因为发现中途有变换后的 RGB 有负数,所以觉得需要给变量添加限制条件,但发现始终都在某个迭代中会有负数,结果就越走越偏...
提一下,我知道有负数是因为有 RuntimeWarning,而 python 中捕获这个的方法是在开头加一个 np.seterr(all='raise')
最后修改
上一步中输出迭代值和迭代次数,发现迭代次数是够用的,但迭代值到后面却不是单调减,所以就怀疑是不是运算有问题。
然后灵感突然来了,这里我是真佩服我自己:原因还是精度问题,要用 np.longdouble 替换 np.float32!!!最后终于搞定...