文章: Color transfer in correlated color space, [paper], [matlab code], [opencv code]
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}
\]
T表示平移, R表示旋轉, S表示縮放. 下標t表示目標影象, 下標s表示原始影象, 文中的原始公式存在問題, 我這裡進行了調整.
因而本文就是尋找這個變換矩陣, 使用的方法是使用SVD分解(關於SVD演演算法, 可以戳這裡: 奇異值分解(SVD) - 知乎 (zhihu.com).)
\[Cov = U \cdot \Lambda \cdot V^T
\]
具體地, 本文演演算法步驟為:
- 計算影象每個顏色通道的均值, 及影象的協方差矩陣
- 對協方差矩陣進行SVD分解
- 構建變換需要的矩陣
- 使用公式對影象進行顏色遷移
2-演演算法核心
對於n維顏色空間, 為了方便處理, 可以調整為n+1維的齊次座標標示. 對於本文, 使用的是RGB 3維顏色空間, 齊次座標維4維的.
對於上述幾個變換矩陣, 平移矩陣T很容易想到, 可以使用各顏色通道的均值來表示. 但對於旋轉矩陣R和縮放矩陣S就需要用到SVD分解矩陣的性質了: \(U\) 表示旋轉, \(\Lambda\) 表示縮放拉伸.
因而所需變換矩陣如下:
\[\Lambda = diag(\lambda^{c1}, \lambda^{c2}, \lambda^{c3})
\]
\[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}
\]
\[R_s = U_s^{-1}, R_t = U_t
\]
\[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} ,
\]
式中, ci表示顏色通道, \(s^{ci}=\sqrt{\lambda^{ci}}\). 這裡取了根號, 如果不取根號是不是也可以???
本文演演算法是對3個通道一起處理, 如果每個通道單獨處理, 上述公式可以等效為:
\[C^i = \frac{\sigma_t^{i}}{\sigma_s^{i}}(C_s^{i} - \mu_s^{i}) + \mu_t^{i}
\]
式中, i表示通道.
3-演演算法效果
如下所示為文中給出的一組結果:
4-補充說明
作者在自己給出的matlab程式碼中指出了本文演演算法存在的一個問題, 我們先來看看實際的情況, 如下所示為一組影象的測試結果.
可以看到, 結果出現了異常. 作者給出的分析是:
- SVD生成的\(\Lambda\) 矩陣中對角線上的值, 是由特徵值從大到小排列的, 源影象和目標影象的這個排列可能不匹配
- 如源影象排列為c1, c2, c3, 目標影象排列為c2, c1, c3
- 即使排列相同, 它們的方向可能相反, 如目標影象排列為c1, -c2, c3
針對這個問題, 作者程式碼實現中給出瞭解決方案, 進行列匹配(matchColumns):
- 對旋轉矩陣\(U_t\) 的所有列進行排列組合, 與\(U_s\) 對應的列求點積和
- 找到和最大的一個組合為最優匹配
- 根據組合中座標軸的順序, 對\(\Lambda_t\) 的順序進行調整, 同時調整方向
下面是調整後的結果: