图像颜色迁移《color transfer between images》

前言

前段时间,在深度学习领域不是有个比较火的方向叫风格迁移的嘛,对于我这种不喜欢深度学习那种不稳定结果的人来说,还是想看看传统图像处理领域有什么类似的技术,发现了一个颜色迁移的算法,很久前的论文了。

国际惯例,参考博客:

理论与对应代码复现

这篇文章的用途在于:利用一张图片的颜色去矫正领一张图片,比如你在昏暗的场景下拍了一张图,但是你发现有一张类似的图颜色非常好,你就可以用这个颜色好的图去矫正你拍的这张昏色图。

正如之前所写的关于颜色协调模型的博客一样,这篇论文也是在某种颜色空间去调整色彩,这个颜色空间通常要求正交化,即更改某个颜色,不会影响到其它属性。颜色协调模型使用的HSV颜色空间,而这篇色彩迁移的论文则是使用了 L α β L\alpha \beta Lαβ空间。都不使用RGB颜色空间的原因就是它并非正交化空间,作者观察到,当蓝色通道值比较大的时候,红色和绿色通道值也很大,由此证明RGB是互相影响的。

RGB转换为lab方法

l α β l\alpha\beta lαβ颜色空间最小化了各通道之间的联系,而且这个颜色空间是对数空间,意味着一阶近似值即通道强度变化同样能够被检测到。

文章介绍了一种方法通过LMS锥形空间,将RGB颜色转换到 l α β l\alpha\beta lαβ颜色空间。

RGB转换到LMS空间包括两个步骤:

  • RGB转换为XYZ三刺激值(tristimulus values)
    注:关于这个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.
    

    作者基于XYZitu601-1 (D65)转换标准,做了一次优化,使得转换矩阵的每行加和为1,这一小步骤的公式表示为
    [ X Y Z ] = [ 0.5141 0.3239 0.1604 0.2651 0.6702 0.0641 0.0241 0.1288 0.8444 ] [ R G B ] \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.02410.32390.67020.12880.16040.06410.8444RGB

  • 获取到XYZ值以后,直接利用下式转换到LMS空间
    [ L M S ] = [ 0.3897 0.6890 − 0.0787 − 0.2298 1.1834 0.0464 0.0000 0.0000 1.0000 ] [ X Y Z ] \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.38970.22980.00000.68901.18340.00000.07870.04641.0000XYZ

最终这一步使用公式表示就很简单了,上面两个矩阵相乘,然后取个对数代表对数空间:
[ L M S ] = log ⁡ { [ 0.3811 0.5783 0.0402 0.1967 0.7244 0.0782 0.0241 0.1288 0.8444 ] [ R G B ] } \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=log0.38110.19670.02410.57830.72440.12880.04020.07820.8444RGB
接下来作者所说的Ruderman介绍了LMS l α β l\alpha\beta lαβ空间的转换方法
[ l α β ] = [ 1 3 0 0 0 1 6 0 0 0 1 2 ] [ 1 1 1 1 1 − 2 1 − 1 0 ] [ L M S ] \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 10006 10002 1111111120LMS
作者说如果将LMS分别当做红绿蓝,那么 l l l代表消色差通道(achromatic channel), β \beta β代表黄蓝通道, β \beta β代表红绿通道。

代码实现如下:

def RGB2LAB(rgb):
    # RGB to LMS
    cvt_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]=1
    lms = np.log10(lms)
    # LMS to lab
    lms_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\beta lαβ分别进行零均值和单位方差化
  • 然后归一化后的原图像各通道乘以目标色图像的 l α β l\alpha\beta lαβ各通道方差,再加上目标色图像的 l α β l\alpha\beta lαβ各通道均值

这样新的源图像的均值和方差就是目标色图像的均值和方差了。

代码实现如下:

def shift_channel(sc,dc):
    # dst image's color to soure image
    s_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_mean
    return shift_sc

lab转换回RGB

这一步作者没做过多说明,直接给出了两个式子
[ L M S ] = 1 0 [ 1 1 1 1 1 − 1 1 − 2 0 ] [ 3 3 0 0 0 6 6 0 0 0 2 2 ] [ 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[111112110]33 00066 00022 [lαβ]

[ R G B ] = [ 4.4679 − 3.5873 0.1193 − 1.2186 2.3809 − 0.1624 0.0497 − 0.2439 1.2045 ] [ L M S ] \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.46791.21860.04973.58732.38090.24390.11930.16241.2045LMS

直接在代码里面码公式就行了。

代码实现如下:

def LAB2RGB(lab):
    #lab to lms
    lab_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中,有兴趣可以去找找,同时文章也同步到微信公众号中,有疑问或者兴趣欢迎公众号私信。

在这里插入图片描述

  • 10
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风翼冰舟

额~~~CSDN还能打赏了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值