图像颜色迁移《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 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,这一小步骤的公式表示为
    [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.02410.32390.67020.12880.16040.06410.8444RGB

  • 获取到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.38970.22980.00000.68901.18340.00000.07870.04641.0000XYZ

最终这一步使用公式表示就很简单了,上面两个矩阵相乘,然后取个对数代表对数空间:
[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=log0.38110.19670.02410.57830.72440.12880.04020.07820.8444RGB
接下来作者所说的Ruderman介绍了LMSlαβ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αβ=310006100021111111120LMS
作者说如果将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_sc

lab转换回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[111112110]330006600022[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.46791.21860.04973.58732.38090.24390.11930.16241.2045LMS

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

代码实现如下:

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中,有兴趣可以去找找,同时文章也同步到微信公众号中,有疑问或者兴趣欢迎公众号私信。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/246569.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ColorSpace颜色空间简介

前言 如果看过之前的介绍的图像颜色迁移《color transfer between images》和颜色协调模型Color Harmoniztion就会发现,大部分图像处理算法虽然输入输出是RGB像素值,但是中间进行算法处理时很少直接更改RGB值,而是转换到其它空间&#xff0c…

Ogre共享骨骼与两种骨骼驱动方法

前言 最近业务中用到Ogre做基于3D关键点虚拟角色骨骼驱动,但是遇到两个问题: 身体、头、眼睛、衣服等mesh的骨骼是分开的,但是骨骼结构都是一样的,需要设置共享骨骼驱动的时候可以直接修改骨骼旋转量,或者将旋转量存…

仿射变换和透视变换

前言 在前面做换脸的博客中提到了使用仿射变换和透视变换将两张不同的人脸基于关键点进行对齐,保证一张人脸贴到另一张人脸时,大小完全一致;所以有必要理解一下这两个概念的区别,由于以实用性为目的,所以所有的图像算…

obj格式解析

前言 最近处理一些网格渲染的时候,需要解析Obj文件,从Free3D上随便找了个免费的人体obj模型解析测试一波 国际惯例,参考博客: 本文所使用的从Free3D下载的模型 .obj文件格式与.mtl文件格式 详解3D中的obj文件格式 3D中OBJ文…

Flask服务部署与简单内网穿透

前言 最近学习部署的时候,想到深度学习里面通常用的部署方法是flask做服务端,然后使用nginx做负载均衡,貌似也能做内网穿透。不过我不太懂负载均衡,只想利用本地电脑搭建一个简单的服务器,实现外部调用API服务的功能。…

OpenCV学习——轮廓检测

前言 轮廓检测是传统视觉中非常常用的功能,这里简单记录一下opencv中的轮廓检测算法使用方法,至于理论,后续有机会再去细品。 国际惯例: OpenCV官方的轮廓检测教程python版 OpenCV中的二值化方法教程 OpenCV轮廓层级官方文档…

RBF神经网络理论与实现

前言 最近发现有挺多人喜欢径向基函数(Radial Basis Function,RBF)神经网络,其实它就是将RBF作为神经网络层间的一种连接方式而已。这里做一个简单的描述和找了个代码解读。 之前也写过一篇,不过排版不好看,可以戳这里跳转 国际惯例&#x…

基于python和unity交互的卡通角色肢体和表情驱动(深度学习)

前言 最近看到了好多卡通角色的肢体驱动的东东,感觉是时候发挥一下读研时候学的东西了,而且虽然现在不炼丹了,但是还是得保持吃丹的技能。这个项目找了很多很多代码进行测试,最终集成了一个3D姿态估计和人脸关键点提取的代码。 …

OpenCV学习——形态学

前言 继续学习图像里面的形态学知识——结构元、腐蚀、膨胀、开运算、闭运算、击中/不击中变换。以及部分基本形态学算法,包括边界提取、空洞填充、连通分量的提取、凸壳、细化、粗化、骨架、裁剪、形态学重建。 其实就是对冈萨雷斯的《数字图像处理》中第9章节《…

径向基函数RBF三维网格变形

前言 之前写过径向基函数(RBF)神经网络做分类或者拟合。然后挖了个坑说在《Phase-Functioned Neural Networks for Character Control》里面提到了用于做地形编辑,所以这篇博客就是解析一下如何用RBF做网格编辑系统。 参考博客: Noe’s tutorial on d…

OBJ可视化——UV还原(修正)

前言 前面写过一篇obj格式解析的博客,但是这篇文章中可视化的工作是参考PRNet的源码进行的,后来细细思考了一下,有点问题,具体看下面。 问题来源 在PRNet源码的render.py中有个函数render_texture,是作者用于将uv展…

Unity中BVH骨骼动画驱动的可视化理论与实现

前言 找了很久使用BVH到unity中驱动骨骼动画的代码,但是都不是特别好用,自己以前写过,原理很简单,这里记录一下。 理论 初始姿态 在BVH或者其它骨骼动画中,一般涉及到三种姿势:A-pose,T-pos…

卡通驱动项目ThreeDPoseTracker——模型驱动解析

前言 之前解析过ThreeDPoseTracker这个项目中的深度学习模型,公众号有兄弟私信一些问题,我刚好对这个项目实现有兴趣,就分析一波源码,顺便把问题解答一下。 这个源码其实包括很多内容:3D姿态估计,坐标平滑…

卡通驱动项目ThreeDPoseTracker——关键点平滑方案解析

前言 之前对ThreeDPoseTracker的深度学习模型和unity中的驱动方法进行过解析,还有一个比较重要的就是从深度学习模型出来的3D关键点数据会有抖动,在ThreeDPoseTracker源码中有做两次平滑,一部分是卡尔曼滤波,还有一部分是低通滤波…

卡通角色表情驱动系列一

前言 分析完ThreeDPoseTracker来做卡通角色的身体驱动,接下来在卡通驱动领域还有一个是表情驱动。对这个真的是一窍不通啊,只能慢慢看论文了。 国际惯例,参考博客/论文: 《Landmark-guided deformation transfer of template f…

opencv相机标定和人头姿态估计案例

前言 头部驱动除了之前关注的表情驱动外,还有眼球驱动和头部方向驱动。本博客基于opencv官方文档和部分开源代码来研究如何基于人脸关键点获取头部的朝向。 国际惯例,参考博客: opencv:Camera Calibration and 3D Reconstruction opencv:…

卡通角色表情驱动系列二

前言 之前介绍了使用传统算法求解BS系数的表情驱动方法,其中提到过的三种方法之一是基于网格形变迁移做的,那么这篇文章就是对《Deformation Transfer for Triangle Meshes》做表情驱动的解析。 国际惯例,参考博客: 论文原文《…

UE自带重定向原理

UE自带重定向方法验证 核心源码在VS的解决方案中的位置: UE4\Source\Developer\AssetTools\Private\AssetTypeActions\AnimSequence.cpp中第3237行RemapTracksToNewSkeleton函数 跳转方法 AssetTypeActions_AnimationAsset.cpp的RetargetNonSkeletonAnimationHa…

【caffe-Windows】caffe+VS2013+Windows无GPU快速配置教程

前言 首先来一波地址: happynear大神的第三方caffe:http://blog.csdn.net/happynear/article/details/45372231 Neil Z大神的第三方caffe:https://initialneil.wordpress.com/2015/01/11/build-caffe-in-windows-with-visual-studio-2013-…

【caffe-Windows】caffe+VS2013+Windows+GPU配置+cifar使用

前言 国际惯例,先来波地址: CUDA WIN7:链接:http://pan.baidu.com/s/1nvyA3Qp 密码:h0f3 官方网址:https://developer.nvidia.com/cuda-toolkit CUDA WIN10:链接:http://pan.baidu.com/s/1…