图像颜色迁移《color transfer between images》
前言
前段時間,在深度學習領域不是有個比較火的方向叫風格遷移的嘛,對于我這種不喜歡深度學習那種不穩定結果的人來說,還是想看看傳統圖像處理領域有什么類似的技術,發現了一個顏色遷移的算法,很久前的論文了。
國際慣例,參考博客:
- 原論文《color transfer between images》
- 大佬的python實現
- 大佬的matlab實現
- 知乎解析《Color transfer between images》
理論與對應代碼復現
這篇文章的用途在于:利用一張圖片的顏色去矯正領一張圖片,比如你在昏暗的場景下拍了一張圖,但是你發現有一張類似的圖顏色非常好,你就可以用這個顏色好的圖去矯正你拍的這張昏色圖。
正如之前所寫的關于顏色協調模型的博客一樣,這篇論文也是在某種顏色空間去調整色彩,這個顏色空間通常要求正交化,即更改某個顏色,不會影響到其它屬性。顏色協調模型使用的HSV顏色空間,而這篇色彩遷移的論文則是使用了LαβL\alpha \betaLαβ空間。都不使用RGB顏色空間的原因就是它并非正交化空間,作者觀察到,當藍色通道值比較大的時候,紅色和綠色通道值也很大,由此證明RGB是互相影響的。
RGB轉換為lab方法
lαβl\alpha\betalαβ顏色空間最小化了各通道之間的聯系,而且這個顏色空間是對數空間,意味著一階近似值即通道強度變化同樣能夠被檢測到。
文章介紹了一種方法通過LMS錐形空間,將RGB顏色轉換到lαβl\alpha\betalαβ顏色空間。
將RGB轉換到LMS空間包括兩個步驟:
-
將RGB轉換為XYZ三刺激值(tristimulus values)
Tristimulus system, a system for visually matching a colour under standardized conditions against the three primary colours—red, green, and blue; the three results are expressed as X, Y, and Z, respectively, and are called tristimulus values.
注:關于這個tristimulus values網上有介紹,也是代表圖像顏色的三個主分量作者基于XYZitu601-1 (D65)轉換標準,做了一次優化,使得轉換矩陣的每行加和為1,這一小步驟的公式表示為
[XYZ]=[0.51410.32390.16040.26510.67020.06410.02410.12880.8444][RGB]\begin{bmatrix} X\\Y\\Z \end{bmatrix}= \begin{bmatrix} 0.5141& 0.3239& 0.1604\\ 0.2651& 0.6702& 0.0641\\ 0.0241& 0.1288& 0.8444 \end{bmatrix}\begin{bmatrix} R\\G\\B \end{bmatrix} ???XYZ????=???0.51410.26510.0241?0.32390.67020.1288?0.16040.06410.8444???????RGB???? -
獲取到XYZ值以后,直接利用下式轉換到LMS空間
[LMS]=[0.38970.6890?0.0787?0.22981.18340.04640.00000.00001.0000][XYZ]\begin{bmatrix} L\\M\\S \end{bmatrix}= \begin{bmatrix} 0.3897& 0.6890& -0.0787\\ -0.2298& 1.1834& 0.0464\\ 0.0000& 0.0000& 1.0000 \end{bmatrix}\begin{bmatrix} X\\Y\\Z \end{bmatrix} ???LMS????=???0.3897?0.22980.0000?0.68901.18340.0000??0.07870.04641.0000???????XYZ????
最終這一步使用公式表示就很簡單了,上面兩個矩陣相乘,然后取個對數代表對數空間:
[LMS]=log?{[0.38110.57830.04020.19670.72440.07820.02410.12880.8444][RGB]}\begin{bmatrix} L\\M\\S \end{bmatrix}=\log\left\{ \begin{bmatrix} 0.3811& 0.5783& 0.0402\\ 0.1967& 0.7244& 0.0782\\ 0.0241& 0.1288& 0.8444 \end{bmatrix}\begin{bmatrix} R\\G\\B \end{bmatrix}\right\} ???LMS????=log???????0.38110.19670.0241?0.57830.72440.1288?0.04020.07820.8444???????RGB????????
接下來作者所說的Ruderman介紹了LMS到lαβl\alpha\betalαβ空間的轉換方法
[lαβ]=[130001600012][11111?21?10][LMS]\begin{bmatrix} l\\\alpha\\\beta \end{bmatrix}= \begin{bmatrix} \frac{1}{\sqrt3}& 0& 0\\ 0& \frac{1}{\sqrt6}& 0\\ 0& 0& \frac{1}{\sqrt2} \end{bmatrix}\begin{bmatrix} 1& 1& 1\\ 1& 1& -2\\ 1& -1& 0 \end{bmatrix}\begin{bmatrix} L\\M\\S \end{bmatrix} ???lαβ????=????3?1?00?06?1?0?002?1?????????111?11?1?1?20???????LMS????
作者說如果將LMS分別當做紅綠藍,那么lll代表消色差通道(achromatic channel),β\betaβ代表黃藍通道,β\betaβ代表紅綠通道。
代碼實現如下:
def RGB2LAB(rgb):# RGB to LMScvt_mat = np.array([[0.3811,0.5783,0.0402],[0.1967,0.7244,0.0782],[0.0241,0.1288,0.8444]])lms = np.zeros_like(rgb)for i in range(rgb.shape[0]):for j in range(rgb.shape[1]):lms[i,j,...] = np.dot(cvt_mat,rgb[i,j,...])lms[lms==0]=1lms = np.log10(lms)# LMS to lablms_lab_mat1 = np.array([[1.0/np.sqrt(3.0),0,0],[0,1.0/np.sqrt(6.0),0],[0,0,1.0/np.sqrt(2.0)]])lms_lab_mat2 = np.array([[1,1,1],[1,1,-2],[1,-1,0]])lms_lab_mat = np.dot(lms_lab_mat1 , lms_lab_mat2)lab = np.zeros_like(lms)for i in range(lms.shape[0]):for j in range(lms.shape[1]):lab[i,j,...] = np.dot(lms_lab_mat,lms[i,j,...])return lab顏色遷移
這一步就不用公式寫了,具體意思就是先將源圖像的均值和方差變換到目標顏色圖像的均值和方差;就純數學的方法;分兩步:
- 源圖像的lαβl\alpha\betalαβ分別進行零均值和單位方差化
- 然后歸一化后的原圖像各通道乘以目標色圖像的lαβl\alpha\betalαβ各通道方差,再加上目標色圖像的lαβl\alpha\betalαβ各通道均值
這樣新的源圖像的均值和方差就是目標色圖像的均值和方差了。
代碼實現如下:
def shift_channel(sc,dc):# dst image's color to soure images_mean = np.mean(sc)d_mean = np.mean(dc)s_std = np.std(sc)d_std = np.std(dc)shift_sc = (sc-s_mean)/s_std * d_std + d_meanreturn shift_sclab轉換回RGB
這一步作者沒做過多說明,直接給出了兩個式子
[LMS]=10[11111?11?20][330006600022][lαβ]\begin{bmatrix} L\\M\\S \end{bmatrix}= 10^{ \begin{bmatrix} 1& 1& 1\\ 1& 1& -1\\ 1& -2& 0 \end{bmatrix} \begin{bmatrix} \frac{\sqrt3}{3}& 0& 0\\ 0& \frac{\sqrt6}{6}& 0\\ 0& 0& \frac{\sqrt2}{2} \end{bmatrix}\begin{bmatrix} l\\\alpha\\\beta \end{bmatrix}} ???LMS????=10[111?11?2?1?10?]????33??00?066??0?0022???????[lαβ?]
[RGB]=[4.4679?3.58730.1193?1.21862.3809?0.16240.0497?0.24391.2045][LMS]\begin{bmatrix} R\\G\\B \end{bmatrix}= \begin{bmatrix} 4.4679& -3.5873& 0.1193\\ -1.2186& 2.3809& -0.1624\\ 0.0497& -0.2439& 1.2045 \end{bmatrix}\begin{bmatrix} L\\M\\S \end{bmatrix} ???RGB????=???4.4679?1.21860.0497??3.58732.3809?0.2439?0.1193?0.16241.2045???????LMS????
直接在代碼里面碼公式就行了。
代碼實現如下:
def LAB2RGB(lab):#lab to lmslab_lms_mat1 = np.array([[1,1,1],[1,1,-1],[1,-2,0]])lab_lms_mat2 = np.array([[np.sqrt(3.0)/3.0,0,0],[0,np.sqrt(6.0)/6.0,0],[0,0,np.sqrt(2.0)/2.0]])lab_lms_mat = np.dot(lab_lms_mat1,lab_lms_mat2)lms = np.zeros_like(lab)for i in range(lab.shape[0]):for j in range(lab.shape[1]):lms[i,j,...] = np.dot(lab_lms_mat,lab[i,j,...])lms = 10**lms# lms to rgb lms_rgb_mat = np.array([[4.4679,-3.5873,0.1193],[-1.2186,2.3809,-0.1624],[0.0497,-0.2439,1.2045]])rgb = np.zeros_like(lms)for i in range(lms.shape[0]):for j in range(lms.shape[1]):rgb[i,j,...] = np.dot(lms_rgb_mat,lms[i,j,...])rgb = np.clip(rgb,0.0,1.0)return rgb最終效果如圖所示:
后記
繼顏色協調模型后的又一篇好玩的關于圖像處理的論文復現。
完整的python腳本實現放在微信公眾號的簡介中描述的github中,有興趣可以去找找,同時文章也同步到微信公眾號中,有疑問或者興趣歡迎公眾號私信。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的图像颜色迁移《color transfer between images》的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 聊聊 webpack 打包如何压缩包文件
- 下一篇: mysql升级-rpm安装