RGB转一维线性色彩空间计算两个颜色的距离.判断颜色是否相近.计算两个颜色的差.

我最近在解决一个问题, 想计算两个小图片的相似性.
为了简化计算我打算把rgb三种颜色的分离数值合并成一个数值. 两种颜色越是相近, 这两个数值的差越小例如 颜色 #000001和颜色#000002的差是1, 数值越小说明两个颜色越相近. 如果事情是这么简单的话就优美了… 但是现实情况却并非如你所料的那么美好.

例如颜色
#ffffff是白色 和颜色 #feffff, 人眼几乎是区分不出来的.可以视为相等, 差应该是1. 但是他们在数学上的两个差值是#010000
这么大,
在这里插入图片描述

有没有什么原始的算法.或相关说明…或者公式?

查过各种各样的资料, 首先想到的就是色彩空间转换. 把RGB转成到某个线性的一维的色彩空间.
经过翻查, 最后的结果是, 很悲剧没有… 根本就没有这种转换…
于是请教大神同学.bluishfish, 以下是对话内容.

名字好难起:
各位, 我最近在解决一个问题, 想计算两个小图片的相似性. 为了简化计算我打算把rgb三种颜色的分离数值合并成一个数值. 也就是合并计算出rgb对应的原始色彩数值.请问我该怎么算? 有没有什么原始的算法.或相关说明…或者公式?

名字好难起:
这个色彩的色彩空间应该是 从0 到 255255255的连续分布.

名字好难起:
在这里插入图片描述

人工智能同学 bluishfish:
 简单合并会丢失大量信息,最好的的“算法”不就是完全独立堆叠么,#FFFFFF 这类表示保留了数据完整性

(作者注, 这里跟我上面的想法是一致的, 简单的堆叠不能解决问题.)

名字好难起:
是的, 你所说的这个我目前也在考虑, 但是这种简单的堆叠 , 数值变化不是一维连续的, 是3维的. 我想找到一种一维的连续线性空间, 能够清楚的计算出两种颜色的相近程度. 越是相近两种颜色的差值越小.

名字好难起:
例如 #FFFFFF 的颜色和#EFFFFF 的差别其实只有一点点. 但是数值差距是 #100000

人工智能同学 bluishfish:
转色彩空间

名字好难起:
我希望这两种颜色的差是1

名字好难起:
好像没有这种色彩空间呢. 都是3维的多.

名字好难起:
我找了半天的资料了

bluishfish:
颜色的话,HSV比较好用

bluishfish:
对人来说直观

名字好难起:
hsv还是3个分量的, 3维形式的色彩空间, 我想转成1维的.

名字好难起:
3维的不好计算 .

名字好难起:
[图片]

bluishfish:
hsv能保证色彩变化是连续的,至于三维转一维通过一个按位加权的函数就能转换了呀

名字好难起:
按位加权能保证相近的颜色在数值上也相近么?

名字好难起:
感觉好像不行.

名字好难起:
顶多和一个颜色相近, 不能保证和另外一个颜色很近.

名字好难起:
也就是说, 3维空间在压缩到1维空间上的时候, 无论如何都不可能把相邻的3个元素放到一起.

bluishfish:
要看你相似度的目标是什么,打个比方,如果是色调偏重,给H偏差加大权重就好,没理解为什么不能压缩到一起

名字好难起:
压缩成一维的目标是, 计算两个颜色的差.

名字好难起:
相近的颜色差值应该是一样的.

名字好难起:
在这里插入图片描述

bluishfish:
H_biasa + S_biasb + V_bias*c 不就好了 a,b,c可以自己定

名字好难起:
例如这个图, 色差为1 其实跟它相近的色差为1的 颜色还有好几个

名字好难起:
3维空间中.

bluishfish:
RGB不连续

bluishfish:
你不能用这个举例

名字好难起:
嗯嗯.

名字好难起:
我大概知道了.

名字好难起:
我想到了更好的方法… 好像向量运算是可以的.

名字好难起:
3维空间的距离的计算必须用向量来算. 遵循向量加减原则.

名字好难起:
MD, 灵光一闪…

bluishfish:
向量只是计算工具呀,本质也是加权

bluishfish:
L2距离或是余弦

名字好难起:
向量运算, 最大的好处是每个维度单独计算, 然后再求和就可以计算出距离了.

bluishfish:
不过RGB不行,因为不连续,只能代表相似性,没有距离概念

名字好难起:
在向量空间里, 还行, 也能算出来距离…

名字好难起:
高等数学真是个好东西.

名字好难起:
@bluishfish 谢谢

那么到这里也就完成了整个算法的基本思考…
光看对话估计不一定能理解我所思考的内容…

我下面稍微说一下, 希望我能讲的清楚.

RGB分别对应着3种颜色, 红,绿,蓝, 缺少其中任何一维都不足以表示出一种色彩…
那么如何才能将这3种信息投射到一条线上?

妈呀, 我感觉词穷了. 不知道怎么描述了.

可以想象成, 把一个足球按相同大小拆碎,按照一定的规则, 排成一条线… (足球代表的是RGB, 这条线就是一维数组空间.)
要求
放在这条线上的时候, 原本在足球上相邻的两个点,放到线上之后也要相邻且差值都相同.

例如,
如下图, 假设红色5代表足球上面最高的哪个点, 那么4,和6 就分别代表着顶点旁边的2个点.
但是实际上足球的最高点有8个距离是1的相邻点,如下图. 先简化看2维效果.
2维看相邻的是9个
一维的只能放2个.相邻点. 剩下的6个是无法在差距为1的情况下放到一根线上的.
在这里插入图片描述
一维空间相邻的两个点位只有2个.无论你怎么排剩下的6个都比这两个要远.

所以, 此路不通. 无法在这种不损失距离的前提条件下, 把3维信息压缩到1维.

后面突然灵光一闪, 还有种数学叫向量. 这里或许可以用的到.
向量可以计算距离. 它是怎么计算的呢? 百度了一下向量.(其实是在聊天的时候百度的)

在这里插入图片描述
转换成我们的问题就是
像素点a = (Ra,Ga,Ba)
像素点b = (Rb,Gb,Bb)

计算两个像素a和b的颜色是否相近的计算公式为

距离 = (Ra-Rb) + (Ga-Gb) + (Ba-Bb)

也就是说每个维度单独计算求出差距,红色减去红色, 绿色减去绿色, 蓝色减去蓝色, 然后再将各维度的差再求和. 就得到两个颜色在RGB色彩空间中的距离.

好了, 本文结束. 后面可以按照这个逻辑开始写代码了.

猜你喜欢

转载自blog.csdn.net/phker/article/details/112987986