文章: Color transfer in correlated color space, [paper], [matlab code], [opencv code]
本文算法比较简单, 其原理是把原始图像本身的空间分布进行归一化, 然后通过旋转平移缩放等变换, 变换到目标图像的空间分布, 如下所示:
I=Tt⋅Rt⋅St⋅St⋅Ss⋅Rs⋅Ts⋅Is(1)I = T_t \cdot R_t \cdot S_t \cdot S_t \cdot S_s \cdot R_s \cdot T_s \cdot I_s \tag{1} I=Tt⋅Rt⋅St⋅St⋅Ss⋅Rs⋅Ts⋅Is(1)
T表示平移, R表示旋转, S表示缩放. 下标t表示目标图像, 下标s表示原始图像, 文中的原始公式存在问题, 我这里进行了调整.
因而本文就是寻找这个变换矩阵, 使用的方法是使用SVD分解(关于SVD算法, 可以戳这里: 奇异值分解(SVD) - 知乎 (zhihu.com).)
Cov=U⋅Λ⋅VTCov = U \cdot \Lambda \cdot V^T Cov=U⋅Λ⋅VT
具体地, 本文算法步骤为:
对于n维颜色空间, 为了方便处理, 可以调整为n+1维的齐次坐标标示. 对于本文, 使用的是RGB 3维颜色空间, 齐次坐标维4维的.
对于上述几个变换矩阵, 平移矩阵T很容易想到, 可以使用各颜色通道的均值来表示. 但对于旋转矩阵R和缩放矩阵S就需要用到SVD分解矩阵的性质了: UUU 表示旋转, Λ\LambdaΛ 表示缩放拉伸.
因而所需变换矩阵如下:
Λ=diag(λc1,λc2,λc3)\Lambda = diag(\lambda^{c1}, \lambda^{c2}, \lambda^{c3}) Λ=diag(λc1,λc2,λc3)
Ts=(100−msc1010−msc2001−msc30001),Tt=(100mtc1010mtc2001mtc30001)T_s = \begin{pmatrix} 1 & 0 & 0 & -m_s^{c1} \\ 0 & 1 & 0 & -m_s^{c2} \\ 0 & 0 & 1 & -m_s^{c3} \\ 0 & 0 & 0 &1 \end{pmatrix} , T_t = \begin{pmatrix} 1 & 0 & 0 & m_t^{c1} \\ 0 & 1 & 0 & m_t^{c2} \\ 0 & 0 & 1 & m_t^{c3} \\ 0 & 0 & 0 &1 \end{pmatrix} Ts=⎝⎜⎜⎛100001000010−msc1−msc2−msc31⎠⎟⎟⎞,Tt=⎝⎜⎜⎛100001000010mtc1mtc2mtc31⎠⎟⎟⎞
Rs=Us−1,Rt=UtR_s = U_s^{-1}, R_t = U_t Rs=Us−1,Rt=Ut
Ss=(1/ssc100001/ssc200001/ssc300001),St=(stc10000stc20000stc300001)S_s = \begin{pmatrix} 1/s_s^{c1} & 0 & 0 & 0 \\ 0 & 1/s_s^{c2} & 0 & 0 \\ 0 & 0 & 1/s_s^{c3} & 0 \\ 0 & 0 & 0 &1 \end{pmatrix} , S_t = \begin{pmatrix} s_t^{c1} & 0 & 0 & 0 \\ 0 & s_t^{c2} & 0 & 0 \\ 0 & 0 & s_t^{c3} & 0 \\ 0 & 0 & 0 &1 \end{pmatrix} Ss=⎝⎜⎜⎛1/ssc100001/ssc200001/ssc300001⎠⎟⎟⎞,St=⎝⎜⎜⎛stc10000stc20000stc300001⎠⎟⎟⎞
式中, ci表示颜色通道, sci=λcis^{ci}=\sqrt{\lambda^{ci}}sci=λci. 这里取了根号, 如果不取根号是不是也可以???
本文算法是对3个通道一起处理, 如果每个通道单独处理, 上述公式可以等效为:
Ci=σtiσsi(Csi−μsi)+μtiC^i = \frac{\sigma_t^{i}}{\sigma_s^{i}}(C_s^{i} - \mu_s^{i}) + \mu_t^{i} Ci=σsiσti(Csi−μsi)+μti
式中, i表示通道.
如下所示为文中给出的一组结果:

作者在自己给出的matlab代码中指出了本文算法存在的一个问题, 我们先来看看实际的情况, 如下所示为一组图像的测试结果.

可以看到, 结果出现了异常. 作者给出的分析是:
针对这个问题, 作者代码实现中给出了解决方案, 进行列匹配(matchColumns):
下面是调整后的结果:
