Escreva um programa que capte uma imagem truecolor padrão e uma única cor RGB de 24 bits (três números de 0 a 255). Modifique a imagem de entrada (ou produza uma nova imagem com as mesmas dimensões) para que sua cor média seja exatamente a única cor que foi inserida. Você pode modificar os pixels na imagem de entrada da maneira que desejar, mas o objetivo é fazer com que as alterações de cores sejam visualmente imperceptíveis quanto possível .
A cor média de uma imagem RGB é realmente um conjunto de três médias aritméticas , uma para cada canal de cores. O valor médio vermelho é a soma dos valores vermelhos em todos os pixels da imagem divididos pelo número total de pixels (a área da imagem), arredondados para o número inteiro mais próximo. As médias verde e azul são calculadas da mesma maneira.
Este Python 2 script (com PIL ) pode calcular a cor média da maioria dos formatos de arquivo de imagem:
from PIL import Image
print 'Enter image file'
im = Image.open(raw_input()).convert('RGB')
pixels = im.load()
avg = [0, 0, 0]
for x in range(im.size[0]):
for y in range(im.size[1]):
for i in range(3):
avg[i] += pixels[x, y][i]
print 'The average color is', tuple(c // (im.size[0] * im.size[1]) for c in avg)
(Existem programas de cores médios semelhantes aqui , mas eles não fazem exatamente o mesmo cálculo.)
O principal requisito para o seu programa é que, para qualquer imagem de entrada, a cor média da saída correspondente deva corresponder exatamente à cor que foi inserida - conforme julgado pelo snippet do Python ou algum código equivalente. A imagem de saída também deve ter exatamente as mesmas dimensões da imagem de entrada.
Assim, você pode enviar tecnicamente um programa que simplesmente colore toda a entrada com a cor média especificada (porque a média sempre seria essa cor), mas esse é um concurso de popularidade - a submissão com o maior número de votos vencerá , e é tão trivial a submissão não recebe muitos votos positivos. Novas idéias, como tirar proveito das peculiaridades da visão humana, ou diminuir a imagem e desenhar uma borda colorida em torno dela (espero), você recebe votos.
Observe que certas combinações de cores e imagens comuns exigem alterações de cor extremamente visíveis. Por exemplo, se a cor média a combinar fosse preta (0, 0, 0), qualquer imagem de entrada precisaria ser totalmente preta, pois se algum pixel tivesse valores diferentes de zero, também tornaria a média diferente de zero ( exceto erros de arredondamento). Lembre-se de tais limitações ao votar.
Imagens de teste
Algumas imagens e suas cores médias padrão para brincar. Clique para ver os tamanhos completos.
A. média (127, 127, 127)
De fejesjoco 's Imagens com todas as cores responder . Original encontrado em seu blog .
B. média (62, 71, 73)
Yokohama . Fornecido por Geobits .
C. média (115, 112, 111)
Tóquio . Fornecido por Geobits .
D. média (154, 151, 154)
Cachoeira de Escher . Original .
E. média (105, 103, 102)
Monte Shasta . Fornecido por mim.
F. média (75, 91, 110)
Notas
- Os formatos exatos de entrada e saída e os tipos de arquivo de imagem usados pelo seu programa não importam muito. Apenas verifique se está claro como usar seu programa.
- Provavelmente, é uma boa ideia (mas não tecnicamente um requisito) que, se uma imagem já tiver a cor média da meta, ela deve ser impressa como está.
- Poste imagens de teste com a entrada de cores média como (150, 100, 100) ou (75, 91, 110), para que os eleitores possam ver as mesmas entradas em diferentes soluções. (Publicar mais exemplos do que este é bom, até incentivado.)
fonte
Respostas:
Python 2 + PIL, escala de cores simples
Aqui está uma abordagem ingênua que deve servir como uma boa linha de base. A cada iteração, comparamos nossa média atual com a média desejada e escalamos o RGB de cada pixel pela proporção correspondente. Temos que ter um pouco de cuidado, porém, por duas razões:
Escalar 0 ainda resulta em 0; portanto, antes de escalar, adicionamos algo pequeno (aqui
0.01
)Os valores RGB estão entre 0 e 255, portanto, precisamos ajustar a proporção para compensar o fato de que a escala de pixels limitados não faz nada.
As imagens são salvas como PNG porque salvar como JPG parece prejudicar as médias de cores.
Saída de amostra
(40, 40, 40)
(150, 100, 100)
(75, 91, 110), paleta Noite estrelada
fonte
C ++, correção de gama
Isso faz um ajuste de brilho da imagem usando uma correção gama simples, com o valor gama determinado separadamente para cada componente para corresponder à média alvo.
As etapas de alto nível são:
Toda entrada / saída de imagem usa arquivos PPM em ASCII. As imagens foram convertidas de / para PNG usando o GIMP. O código foi executado em um Mac, as conversões de imagem foram feitas no Windows.
Código:
O código em si é bastante direto. Um detalhe sutil, mas importante, é que, enquanto os valores das cores estão no intervalo [0, 255], mapeio-os para a curva gama como se o intervalo fosse [-1, 256]. Isso permite que a média seja forçada a 0 ou 255. Caso contrário, 0 permanecerá sempre 0 e 255 permanecerá sempre 255, o que talvez nunca permita uma média de 0/255.
Usar:
.cpp
, por exemploforce.cpp
.c++ -o force -O2 force.cpp
../force input.ppm targetR targetG target >output.ppm
.Saída de amostra para 40, 40, 40
Observe que as imagens para todas as amostras maiores são incluídas como JPEGs, pois elas excedem o limite de tamanho SE como PNGs. Como o JPEG é um formato de compactação com perdas, eles podem não corresponder exatamente à média de destino. Eu tenho a versão PNG de todos os arquivos, que corresponde exatamente.
Saída de amostra para 150, 100, 100:
Saída de amostra para 75, 91, 110:
fonte
Python 2 + PIL
Isso percorre cada pixel em uma ordem aleatória e reduz a distância entre cada componente da cor do pixel e
255
ou0
(dependendo se a média atual é menor ou maior que a média desejada). A distância é reduzida por um fator multiplicativo fixo. Isso é repetido até que a média desejada seja obtida. A redução é sempre pelo menos1
, a menos que a cor seja255
(ou0
), para garantir que o processamento não seja interrompido quando o pixel estiver perto de branco ou preto.Saída de amostra
(40, 40, 40)
(150, 100, 100)
(75, 91, 110)
fonte
Java
Uma abordagem baseada em RNG. Um pouco lento para imagens de entrada grandes.
Testes:
(40,40,40)
(150.100.100)
(75,91.110)
fonte