怎么算法斗颜色?
这是一个相当困难的问题,目前也没有完美的答案,我尝试从以下几个角度来论述。
1. 色彩的基本原理 人眼是如何分辨颜色的? 答案是 人眼是依靠三种不同视者(trichromats)或者两种视者(dichromats)对不同波长的光刺激产生差异的反应。 例如对于三色视者,他们能够将三原色(红R、绿G、蓝B)混合出所有的颜色;而对于双色视者,他们只能区分两原色(红R与蓝B),所有由这两种颜色混合而成的中色调都是不可分的。 如果将一个图像的每一个像素用三个数字表示(R G B每个颜色各一个数字)的话,那么对于一个三色者来说他看到的就是一个3个N维空间组成的图像,而对于双色者看到的则是2个N维空间的图像。 对于计算机图像处理来说,只要知道视者的类型和图像所采用的颜色编码就可以得到一个正确的效果。 但是如果视者是三色者的时候,这个问题就非常简单了由于三色者能够区分所有中色调所以可以采用灰度图(0-255一共256级灰度)的方式来保存,然后通过不同强度组合的方式重现全部中色调最后组合成一个新的彩色图像。 这个方法是最简单最直观的还原彩色图像的方法,但是存在两个问题:首先是人眼对弱光非常敏感,在弱光环境下人们很容易觉得照片很暗而强行调高亮度从而让照片看起来极为不自然;第二个问题是不同人眼睛对不同的颜色敏感程度不一样,这就会造成同一个色彩在两个人眼里有所不同,这样如果按照某个固定的公式来计算颜色就会错得离谱。
为了解决这两个问题,人们想出了多种改进的方法。 其中最为核心的概念就是色调矢量(hue vector)。 简言之就是认为每一个色调都可以用一个向量来表示,然后利用这个向量来进行颜色匹配。 这样当遇到两个色调的时候(比如两个像素),只要找到其中一个朝向量的方向和一个长度就可以确定两者之间的色彩差别,进而加到原来图像上去。 为了找到这个方向向量和长度,需要找到一个标准样本,然后对比待求样本和它之间的距离,也就是找到最佳的匹配。由于人眼对色调十分敏感,而对明暗强弱不是很敏感,因此最佳匹配并不是最好的亮度匹配,这样的做法会让最终的效果显得很不自然。为了消除这种效果,可以在寻找最佳匹配的时候加入一个反差的参数,在得到最佳匹配后同时根据反差参数的大小反推到合适的亮度值。
2. 色彩的空间概念 从上面的讨论可以看到,计算色彩主要是计算两个颜色之间的差分,于是就可以引入离散数学中的对称距离,而这个距离还有一个很好玩的性质——平方关系。
因为 对任意两个像素的点积 其中 和 分别代表两个像素的所有分量, 而 则是一个归一化的常数,这个式子的意义是两个像素点所有分量平方后的几何距离。而这个距离正好和我们常用到的欧几里德距离有着平方的关系。正因为如此,我们可以通过一个简单的变换将色彩空间映射到一个更高维的空间里去,而新空间的基是标准样本的坐标,这样就可以通过一个低维的空间内进行计算,而在最终还原的时候再把结果投影回来。这样的处理方法能极大地提高计算的效率,并且不会引起算力的急剧下降,是个正交变换。
在计算机图像处理里面常用的色彩空间有RGB、HSV、HSI以及CMYK等等。这些色彩空间都有一个共同点,就是R、G、B这三个分量构成了一个立方体,而另外两个分量则是由这三个分量线性决定。这就意味着如果先找到R、G、B这三个分量的一个最佳分配,然后固定他们的值,就可以通过调整另外一个分量的值来调节整个色彩的空间。这种预先规定好一个色彩分配的方案叫做色彩模型。
常见的色彩模型还有CIE RGB和YUV等。 以上只是介绍了如何实现算法斗色彩的步骤,至于具体如何实现各个步骤的具体算法这里就不一一展开了,感兴趣的朋友可以查看我之前写的这篇文章。