Tirando a subjetividade de análises de cores: como utilizar clusterização para agrupar

Monique Schreiner
gb.tech
Published in
5 min readAug 25, 2023
Uma mulher e um homem olhando para um quadro num galeria de arte. O quadro possui uma cor sólida num tom entre um verde e um azul. Há um balão de fala na mulher escrito “É azul!” e outro no homem escrito “É verde!”.

Se duas pessoas forem encarregadas de separar uma série de tons em dois grupos de cores, azuis e verdes, elas colocariam os mesmos tons nos mesmos grupos? Provavelmente não. Isso porque a percepção de cores pelo ser humano é algo bastante subjetiva e varia de pessoa para pessoa: o que uma pessoa considera um tom de verde, outra pessoa pode considerar um tom de azul. Consequentemente, apesar de parecer simples, a tarefa de agrupar cores pode acabar se tornando bastante complexa.

Além de questões culturais, alguns processos do próprio corpo humano acabam influenciando no modo que enxergamos as cores. Por exemplo, tendemos a assemelhar a cor de uma imagem com as cores dos objetos que a cercam e, dessa forma, acabamos percebendo cores idênticas como se fossem diferentes.

Imagem com fundo composto por listras nas cores vermelha, azul e verde. Várias bolas amarelas estão sobre o fundo. Em cada bola, uma cor de linha fica sobreposta a ela. Acontece uma ilusão em que a cor da bola se assemelha à cor da linha que passa sobre ela.
Ilusão de Munker-White: todas as bolas têm exatamente a mesma cor, porém acabamos percebendo cores diferentes de acordo com a cor das linhas que atravessam elas.

Além disso, o processo evolutivo do ser humano fez com que nosso cérebro tenha um mecanismo que tenta descontar os efeitos de fontes de luz (às vezes mais azulada, às vezes mais amarelada) para tentar chegar a uma cor “verdadeira”.

Foto de um vestido azul com listras horizontais pretas. Porém, de acordo com as condições de luz, ele pode ser visto como branco com listras douradas.
A famosa polêmica do vestido branco/dourado ou preto/azul. A cor original é preta e azul, mas nosso cérebro pode entender que os tons azulados são efeito da luz. Descontando esse efeito, acabamos enxergando branco e dourado.

Mas como cientista de dados, podemos diminuir a subjetividade e tornar o processo de agrupamento de cores mais eficaz e menos manual seguindo alguns passos.

Passo 1: Representando as cores de forma numérica

Há diversas formas de representar cores numericamente. Uma das formas mais comuns são as representações RGB e HEX que são baseadas em como as cores são geradas em monitores. O RGB é composto de três valores que vão dizer a quantidade vermelho (Red), verde (Green) e azul (Blue) que vão compor uma cor. Já o HEX é uma “abreviação” que resume os valores de RGB em apenas seis dígitos usando o sistema hexadecimal.

Porém, optamos por usar a representação CIELAB, mais conhecida por L*a*b*. Essa representação é mais consistente com a forma que o olho humano percebe as cores e é o padrão usado em equipamentos da indústria e em laboratórios. Na representação L*a*b*, as cores são representadas por três valores:

  • L*: indica a luminosidade
  • a*: indica a variação entre vermelho e verde
  • b*: indica a variação entre amarelo e azul

Dessa forma, conseguimos plotar as todas as cores que temos em um espaço tridimensional.

Dois gráficos tridimensionais. Ambos os gráficos mostram três eixos: eixo y com valores de L* (menor valor sendo preto e maior valor sendo branco); eixo x com valores de a* (menor valor sendo verde e maior sendo vermelho); eixo z com valores de b* (menor valor sendo azul e maior sendo amarelo).O gráfico da esquerda mostra somente os eixos explicados e o da direita mostra a variação das cores de acordo com a variação dos valores nos eixos.

Passo 2: Definindo os grupos de cores

Com os valores L*a*b* das cores em mãos, precisamos decidir em quantos e quais grupos queremos agrupar essas cores. Para cada objetivo, teremos grupos de cores diferentes, como por exemplo:

  • Para agrupar cores de vinhos podemos ter 3 grupos: Vinhos brancos, Rosés e Tintos.
  • Para agrupar cores de cabelos podemos ter 5 grupos: Loiros, Castanhos, Pretos, Ruivos e Grisalhos.

Com os grupos decididos, devemos escolher manualmente algumas cores que representam cada um dos grupos, são essas cores que usaremos como base para classificar as outras. Utilizando os valores de L*a*b* desses representantes, podemos calcular os valores que correspondem à cor centróide de cada um dos grupos. Aqui, o centróide nada mais é que o ponto com os valores médios de L*a*b* dos representantes escolhidos para o grupo. Desta forma, cada grupo de cor terá um valor de L*a*b* que o representa. Ou seja, se estivermos trabalhando com cores de cabelo, teremos 5 valores de L*a*b* centróides, um para cada grupo (Loiros, Castanhos, Pretos, Ruivos e Grisalhos).

Gráfico com os valores de b* representados no eixo y e valores de a* no eixo x. O gráfico mostra vários pontos vermelhos dispersos e, no valor correspondente ao centróide, uma cruz está marcada.
O gráfico mostra os valores de a* e b* para as cores escolhidas como representantes de um grupo. A cruz mostra o centróide do grupo.

Passo 3: Classificando as cores usando clusterização

Por fim, para classificar todas as cores nos grupos, podemos usar um modelo de clusterização. Existem diversas metodologias de clusterização (K-means, clusterização hierárquica, DBSCAN, GMM, entre outros). A abordagem escolhida foi o K-means.

No algoritmo de clusterização K-means, definimos o número de clusters desejados (K) e o algoritmo irá calcular os centróides ótimos de cada cluster e classificar cada ponto baseado no centróide mais próximo.

Na esquerda, gráfico com pontos dispersos e o título “Unlabelled Data”. Na direita, o mesmo gráfico, porém com os pontos agrupados em 3 clusters (um representado pela cor verde, um vermelho e outro azul), no centro de cada cluster há um x representando o centróide. Entre os dois gráficos, há uma seta indo da esquerda para a direita com a palavra “K-means” sobre ela.
Exemplo de classificação de dados utilizando K = 3. Cada cluster tem seu centróide calculado e todos os pontos recebem uma classificação baseada no centróide mais próximo.

No nosso caso, já sabemos de antemão quantos grupos temos e quais são seus centróides. Então temos que “forçar” o algoritmo a usar os centróides que calculamos para cada grupo de cor. Dessa forma, toda vez que usarmos o modelo para categorizar uma cor, essa cor será categorizada com base nos grupos que criamos no passo anterior.

Para fazer isso no python, podemos utilizar a função KMeans do pacote scikit-learn. Para forçar os centróides a serem os que decidimos, basta treinar o modelo somente com os valores dos centróides e setar o número de clusters para o número de centróides. Por exemplo, usando os grupos de cores de cabelos (Loiros, Castanhos, Pretos, Ruivos e Grisalhos), nosso número de clusters (K) seria 5 e o modelo seria treinado somente com os 5 centróides calculados no passo 2.

from sklearn.cluster import KMeans

X = centroides
y = cores

N_CLUSTERS = len(centroides)

kmeans = KMeans(n_clusters=N_CLUSTERS, random_state=0).fit(X)

Após treinar o modelo, podemos fazer a predição para todas as cores, e conseguimos classificar todas em algum grupo, eliminando a arbitrariedade da classificação.

# Classificando as cores nos grupos

pred_cores = kmeans.predict(y)

Utilizando um processo simples de Data Science, conseguimos classificar um grande volume de cores de forma rápida, eliminando as incertezas e complicações que a percepção humana traz ;)

--

--