Já pensou se fosse possível extrair cores automaticamente de imagens, utilizando técnicas estatísticas? Na verdade, isso é possível sim. Tome a foto abaixo, por exemplo, tirada da minha página sobre fotografia:
Não é difícil ver que as cores predominantes são os tons azuis, do mais claro ao mais escuro. Há um pouco de vinho e branco também. Quando questionado sobre essa paleta de cores, o computador retorna o seguinte:
Se pedirmos para ele ser mais específico, ele pode retornar uma paleta de 15 cores:
Nesse caso, estou usando uma técnica estatística de clusterização (ou agrupamento) de dados, chamada k-means. Meu curso de Introdução à Modelagem de Big Data trata dela com detalhes mas, em linhas gerais, o que está sendo feito aqui é o seguinte:
- A imagem é lida dentro do R
- Cada pixel é interpretado como um vetor em um espaço de três dimensões chamado RGB: R (red), G (green) e B (blue)
- Para cada centro de cluster (ou média de cores dos pixels) são calculadas as distâncias entre esse centro e as outras observações
- Determina-se quais observações pertencem a cada cluster
- Se há alguma mudança no pertencimento de um pixel a algum cluster, uma nova média é calculada
- Os passos 3 a 5 são repetidos até a convergência
Com isso, cada imagem considerada tem a sua paleta de cores estimada. O código capaz de fazer isso de modo semi-automático está abaixo:
library(jpeg)
library(scales)
imagem <- readJPEG("fotos/Galinhos_01.jpg")
dimensao <- dim(imagem)
imagem_rgb <- data.frame(
x = rep(1:dimensao[2], each = dimensao[1]),
y = rep(dimensao[1]:1, dimensao[2]),
R = as.vector(imagem[,,1]),
G = as.vector(imagem[,,2]),
B = as.vector(imagem[,,3])
)
k_means <- kmeans(imagem_rgb[, c("R","G","B")], centers = 5, iter.max = 30)
show_col(rgb(k_means$centers))
Com isso, pensei em verificar quais seriam as paletas de cores fotos que coloquei na minha página sobre fotografia, de modo a encontrar algum padrão nas minhas criações. O resultado de algumas delas está a seguir:
# funcao para criar paleta de cores
paleta <- function(imagem, n, show = FALSE){
# pacotes necessarios
require(jpeg)
require(scales)
# le a imagem
imagem <- readJPEG(imagem)
# dimensoes da imagem
dimensao <- dim(imagem)
# encontra os valores rgb de cada pixel
imagem_rgb <- data.frame(
x = rep(1:dimensao[2], each = dimensao[1]),
y = rep(dimensao[1]:1, dimensao[2]),
R = as.vector(imagem[,,1]),
G = as.vector(imagem[,,2]),
B = as.vector(imagem[,,3])
)
# ecnontra
k_means <- kmeans(imagem_rgb[, c("R","G","B")],
centers = n,
algorithm = "Lloyd",
iter.max = 100)
# mostra a paleta
if(show){
show_col(rgb(k_means$centers))
}
# retorna a paleta
return(k_means$centers)
}
library(tidyverse)
arquivos <- list.files(path = "fotos/") %>%
paste("fotos/", ., sep = "")
include_graphics(arquivos[1])
paleta(arquivos[1], n = 5, show = TRUE)
## R G B
## 1 0.3453252695 0.4652132110 0.6127733220
## 2 0.0009807818 0.0005065415 0.0005667995
## 3 0.4647979780 0.4464256001 0.4724367009
## 4 0.6501226612 0.3834856562 0.2484259031
## 5 0.5556619923 0.5523450580 0.5760447112
include_graphics(arquivos[6])
paleta(arquivos[6], n = 5, show = TRUE)
## R G B
## 1 0.02604081 0.5662119 0.8437375
## 2 0.26415689 0.3127395 0.3341804
## 3 0.27803649 0.6476604 0.8609292
## 4 0.02862637 0.4629096 0.6790015
## 5 0.75758265 0.6901154 0.5498935
include_graphics(arquivos[12])
paleta(arquivos[12], n = 5, show = TRUE)
## R G B
## 1 0.12756970 0.17743675 0.29440310
## 2 0.30195066 0.32433943 0.44542976
## 3 0.18677613 0.22270636 0.34081958
## 4 0.01691853 0.01704009 0.01136286
## 5 0.24144840 0.27281474 0.39456082
include_graphics(arquivos[15])
paleta(arquivos[15], n = 5, show = TRUE)
## R G B
## 1 0.9402988 0.6951377 0.03013687
## 2 0.4663403 0.3231593 0.09826148
## 3 0.6479363 0.4175421 0.03824434
## 4 0.5798695 0.4519273 0.30525098
## 5 0.3265524 0.2130330 0.05912327
include_graphics(arquivos[19])
paleta(arquivos[19], n = 5, show = TRUE)
## R G B
## 1 0.5054358 0.4584468 0.4607231
## 2 0.1368853 0.2207605 0.2972571
## 3 0.2661679 0.3339573 0.4234758
## 4 0.8238264 0.6826300 0.5568284
## 5 0.8529453 0.5603634 0.3740310
Embora a técnica não tenha dado o resultado ideal em alguns casos, é possível extrair algumas informações interessantes. Por exemplo, aparentemente, tenho uma preferência por tons azuis e amarelos nas minhas fotos, mas poucos verdes e vemelhos. Muitos tons terrosos também aparecem nos meus trabalhos.