Você recebe uma imagem em cores reais. Sua tarefa é gerar uma versão dessa imagem, que parece ter sido pintada usando tinta por números (a atividade das crianças, não os nonogramas). Junto com a imagem, você recebe dois parâmetros: P , o tamanho máximo da paleta de cores (ou seja, o número máximo de cores distintas para usar) e N , o número máximo de células a serem usadas. Seu algoritmo não precisa usar todas as cores P e N células, mas não deve usar mais que isso. A imagem de saída deve ter as mesmas dimensões que a entrada.
Uma célula é definida como uma área contígua de pixels, todos com a mesma cor. Pixels tocando apenas em um canto não são considerados contíguos. As células podem ter orifícios.
Em resumo, você deve aproximar a imagem de entrada com apenas N áreas com sombra plana / cor sólida e P cores diferentes.
Apenas para visualizar os parâmetros, aqui está um exemplo muito simples (para nenhuma imagem de entrada específica; mostrando minhas habilidades loucas de pintura). A imagem a seguir tem P = 6 e N = 11 :
Aqui estão algumas imagens para testar seu algoritmo (principalmente nossos suspeitos de sempre). Clique nas imagens para versões maiores.
Inclua alguns resultados para diferentes parâmetros. Se você deseja mostrar um grande número de resultados, pode criar uma galeria no imgur.com , para manter o tamanho das respostas razoáveis. Como alternativa, coloque miniaturas em sua postagem e faça links para imagens maiores, como fiz acima. Além disso, fique à vontade para usar outras imagens de teste, se encontrar algo legal.
Suponho que parâmetros em torno de N ≥ 500 , P ~ 30 sejam semelhantes aos modelos reais de pintura por número.
Como é um concurso de popularidade, ganha a resposta com o maior número de votos. Os eleitores são incentivados a julgar as respostas
- quão bem as imagens originais são aproximadas.
- quão bem o algoritmo funciona em diferentes tipos de imagens (as pinturas provavelmente são geralmente mais fáceis do que as fotografias).
- quão bem o algoritmo funciona com parâmetros muito restritivos.
- quão orgânica / suave são as formas das células.
Usarei o seguinte script do Mathematica para validar os resultados:
image = <pastedimagehere> // ImageData;
palette = Union[Join @@ image];
Print["P = ", Length@palette];
grid = GridGraph[Reverse@Most@Dimensions@image];
image = Flatten[image /. Thread[palette -> Range@Length@palette]];
Print["N = ",
Length@ConnectedComponents[
Graph[Cases[EdgeList[grid],
m_ <-> n_ /; image[[m]] == image[[n]]]]]]
O Sp3000 teve a gentileza de escrever um verificador no Python 2 usando PIL, que você encontra nesta pasta .
fonte
Respostas:
Python 2 com PIL ( Galeria )
Tempo de atualização! Esta atualização apresenta um algoritmo de suavização simples para fazer com que as imagens pareçam menos confusas. Se eu atualizar novamente, terei que reformular uma boa parte do meu código, porque está ficando bagunçado e eu não consigo atualizar o meu código.
Também fiz cores de peso k-médias baseadas no tamanho das células, que perdem alguns detalhes para parâmetros mais restritivos (por exemplo, o centro da nebulosa e o forcado da American Gothic), mas tornam a escolha geral mais nítida e agradável. Curiosamente, ele perde todo o fundo das esferas rastreadas por raios para P = 5.
Resumo do algoritmo:
O tempo de processamento de cada imagem depende muito de seu tamanho e complexidade, com tempos que variam de 20 segundos a 7 minutos para as imagens de teste.
Como o algoritmo usa randomização (por exemplo, mesclagem, k-means), você pode obter resultados diferentes em execuções diferentes. Aqui está uma comparação de duas execuções para a imagem do urso, com N = 50 e P = 10:
Nota: Todas as imagens abaixo são links. A maioria dessas imagens é direta desde a primeira execução, mas se eu não gostei da saída, me permiti até três tentativas de ser justa.
N = 50, P = 10
N = 500, P = 30
Mas eu sou muito preguiçoso quando se trata de pintar por cores, então apenas por diversão ...
N = 20, P = 5
Além disso, é divertido ver o que acontece quando você tenta espremer 1 milhão de cores em N = 500, P = 30:
Aqui está uma explicação passo a passo do algoritmo da imagem subaquática com N = 500 e P = 30, na forma de GIF animado:
Também fiz uma galeria para as versões anteriores do algoritmo aqui . Aqui estão alguns dos meus favoritos da última versão (de quando a nebulosa tinha mais estrelas e o urso parecia mais peludo):
fonte
im = im.convert("RGB")
é necessário para algumas fotos. Vou colocar isso depois que reestruturar um pouco o código.Python 2 com PIL
Também uma solução Python e provavelmente muito um trabalho em andamento:
O algoritmo segue uma abordagem diferente da do SP3000, começando pelas cores primeiro:
Encontre uma paleta de cores P por meio de agrupamento k-means e pinte a imagem nessa paleta reduzida.
Aplique um leve filtro mediano para se livrar de algum ruído.
Faça uma lista de todas as células monocromáticas e classifique-as por tamanho.
Mesclar as células menores com o respectivo vizinho maior até restarem apenas N células.
Há bastante espaço para melhorias, tanto em termos de velocidade quanto de qualidade dos resultados. Especialmente, a etapa de fusão das células pode levar muitos minutos e fornece resultados longe de ótimos.
P = 5, N = 45
P = 10, N = 50
P = 4, N = 250
P = 11, N = 500
fonte
Mathematica
No momento, é necessário o número de cores e o raio gaussiano a serem usados no filtro gaussiano. Quanto maior o raio, maior o desfoque e a mesclagem de cores.
Como não permite a inserção do número de células, não atende a um dos requisitos básicos do desafio.
A saída inclui o número de células para cada cor e também o número total de células.
Atualizar
quantImage2
permite especificar o número desejado de células como entrada. Ele determina o melhor raio gaussiano percorrendo cenários com raios maiores até encontrar uma correspondência próxima.quantImage2
saídas (imagem, células solicitadas, células usadas, erro, raio gaussiano usado).É, no entanto, muito lento. Para economizar tempo, você pode começar com um raio inicial, cujo valor padrão é 0.
Exemplo para o qual especificamos o número de células desejado na saída.
Exemplo solicitando 90 células com 25 cores. A solução retorna 88 células, 2% de erro. A função escolheu o raio gaussiano de 55. (Muita distorção).
Exemplos para os quais a entrada inclui o raio gaussiano, mas não o número de células.
25 cores, raio gaussiano de 5 pixels
Três cores, raio de 17 pixels
Vinte cores, raio de 17 pixels
Aumentamos o número de cores, mas não o foco. Observe o aumento no número de células.
Seis cores, raio de 4 pixels
Noite estrelada
Com apenas 6 cores e 60 células. Há uma incompatibilidade de cores nas cores das
showColors
reivindicações usadas. (O amarelo não aparece entre as 5 cores, mas é usado no desenho.) Vou ver se consigo descobrir isso.fonte
showColors
, percorrendo um intervalo de números de cores e raios e escolhendo a combinação que mais se aproxima do número desejado de células. Não tenho certeza se eu tenho o gás para fazer isso no momento. Talvez mais tarde.Python 2 com PIL
Isso ainda é um trabalho em andamento. Além disso, o código abaixo é uma bagunça horrível de espaguete e não deve ser usado como inspiração. :)
Como funciona
O programa divide a tela em
P
regiões, cada uma das quais consiste em um número de células sem furos. Inicialmente, a tela é apenas dividida em quadrados aproximados, que são atribuídos aleatoriamente às regiões. Em seguida, essas regiões são "deformadas" em um processo iterativo, em que um determinado pixel pode mudar sua região seA última condição pode ser aplicada localmente, portanto o processo é um pouco como um autômato celular. Dessa forma, não precisamos fazer nenhuma busca de caminho ou algo assim, o que acelera bastante o processo. No entanto, como as células não podem ser quebradas, algumas delas terminam como "filamentos" que limitam outras células e inibem seu crescimento. Para corrigir isso, existe um processo chamado "corte de filamento", que ocasionalmente quebra uma célula em forma de filamento em duas, se houver menos do que as
N
células naquele momento. As células também podem desaparecer se o tamanho for 1, e isso abre espaço para os cortes dos filamentos.O processo termina quando nenhum pixel tem o incentivo para mudar de região e, depois disso, cada região é simplesmente colorida por sua cor média. Geralmente haverá alguns filamentos restantes na saída, como pode ser visto nos exemplos abaixo, especialmente na nebulosa.
P = 30, N = 500
Mais fotos depois.
Algumas propriedades interessantes do meu programa são probabilísticas, de modo que os resultados podem variar entre diferentes execuções, a menos que você use a mesma semente pseudo-aleatória, é claro. A aleatoriedade não é essencial, porém, eu só queria evitar artefatos acidentais que possam resultar da maneira particular em que o Python percorre um conjunto de coordenadas ou algo semelhante. O programa tende a usar todas as
P
cores e quase todas asN
células, e as células nunca contêm furos por design. Além disso, o processo de deformação é bastante lento. As bolas coloridas levaram quase 15 minutos para serem produzidas na minha máquina. No lado positivo, você liga oGRAPHICAL_LOGGING
Como opção, você obterá uma série legal de fotos do processo de deformação. Transformei as da Mona Lisa em uma animação GIF (reduzi 50% para reduzir o tamanho do arquivo). Se você olhar atentamente para o rosto e o cabelo dela, poderá ver o processo de corte do filamento em ação.fonte