Algoritmo para verificar a similaridade de colors

Eu estou procurando um algoritmo que compara duas colors RGB e gera um valor de sua semelhança (onde similaridade significa “semelhante em relação à percepção humana média”).

Alguma ideia?

EDITAR :

Como não posso mais responder, decidi colocar minha “solução” como uma edição da pergunta.

Eu decidi ir com um subconjunto (muito) pequeno de colors reais no meu aplicativo, para que eu possa lidar com a comparação de colors por conta própria. Eu trabalho com cerca de 30 colors e uso distâncias codificadas entre eles.

Como era um aplicativo para iPhone, trabalhei com o objective-C e a implementação é mais ou menos uma matriz representando a tabela abaixo, que mostra as distâncias entre as colors.

insira a descrição da imagem aqui

A distância RGB no espaço euclideano não é muito “semelhante à média da percepção humana”

Você pode usar o espaço de cor YUV , leva em conta este fator:

insira a descrição da imagem aqui

Você também pode usar o espaço de colors CIE para essa finalidade.

EDITAR:

Devo mencionar que o espaço de colors YUV é uma aproximação barata que pode ser calculada através de fórmulas simples. Mas não é perceptivelmente uniforme. Perceptualmente uniforme significa que uma alteração da mesma quantidade em um valor de cor deve produzir uma mudança de aproximadamente a mesma importância visual. Se você precisa de uma métrica mais precisa e rigorosa, você deve definitivamente considerar o espaço de colors CIELAB ou um outro espaço perceptualmente uniforme (mesmo que não haja fórmulas simples para conversão).

Eu recomendaria usar CIE94 (DeltaE-1994), é dito ser uma representação decente da percepção da cor humana. Eu usei bastante isso em meus aplicativos relacionados à visão de computador, e estou bastante feliz com o resultado.

No entanto, é bastante computacional dispendioso realizar essa comparação:

  1. RGB to XYZ para ambas as colors
  2. XYZ to LAB para ambas as colors
  3. Diff = DeltaE94(LABColor1,LABColor2)

Fórmulas (pseudocódigo):

A percepção humana é mais fraca em chroma do que em intensidade.

Por exemplo, em vídeo comercial, os espaços de colors YCbCr / YPbPr (também chamados Y’UV) reduzem a resolução das informações de croma, mas preservam a luma (Y). Na compression de vídeo digital como 4: 2: 0 e 4: 2: 2 reduz a taxa de bits de crominância devido à percepção relativamente mais fraca.

Eu acredito que você pode calcular uma function de distância dando prioridade sobre luma (Y) e menos prioridade sobre chroma.

Além disso, sob baixa intensidade, a visão humana é praticamente preta e branca. Portanto, a function de prioridade é não-linear em que para baixa luma (Y) você coloca menos e menos peso no croma.

Mais fórmulas científicas: http://en.wikipedia.org/wiki/Color_difference

A percepção de colors não é euclidiana. Qualquer fórmula de distância será boa e terrível ao mesmo tempo. Qualquer medida baseada na distância euclidiana (RGB, HSV, Luv, Lab, …) será boa o suficiente para colors semelhantes, mostrando o aqua próximo da cerceta. Mas para valores não próximos, isso é arbitrário. Por exemplo, o vermelho está mais perto de verde ou azul?

De Charles Poynton’s Color FAQ :

Os sistemas XYZ e RGB estão longe de exibir uniformidade perceptual. Encontrar uma transformação de XYZ em um espaço razoavelmente perceptualmente uniforme consumiu uma década ou mais na CIE e, no final, nenhum sistema único poderia ser acordado.

Há um excelente artigo sobre as distâncias de colors aqui: http://www.compuphase.com/cmetric.htm

Caso esse recurso desapareça, a conclusão do autor é que a melhor aproximação de baixo custo para a distância entre duas colors RGB pode ser obtida usando essa fórmula (em código).

 typedef struct { unsigned char r, g, b; } RGB; double ColourDistance(RGB e1, RGB e2) { long rmean = ( (long)e1.r + (long)e2.r ) / 2; long r = (long)e1.r - (long)e2.r; long g = (long)e1.g - (long)e2.g; long b = (long)e1.b - (long)e2.b; return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8)); } 

A similaridade de cor no cubo RGB é medida pela distância euclidiana (use a fórmula de Pitágoras).

EDIT: Em um segundo pensamento, isso deve ser verdade para a maioria dos outros espaços de colors também.