O MS Paint sempre desperdiçou muito tempo, mas foi evitado pela maioria dos designers gráficos. Talvez as pessoas tenham perdido o interesse por causa da paleta de cores estridente ou por causa dos níveis limitados de desfazer. Independentemente disso, ainda é possível gerar imagens bonitas apenas com o pincel padrão e a paleta de cores padrão.
Desafio
Usando apenas o pincel padrão (um quadrado 4x4 sem cantos) e a paleta de cores padrão (as 28 cores abaixo), tente replicar uma imagem de origem usando uma técnica baseada em subidas estocásticas .
Algoritmo
Toda resposta deve seguir o mesmo algoritmo básico (subida estocástica). Os detalhes podem ser ajustados em cada etapa. Um movimento é considerado uma pincelada (por exemplo, clicar na tinta).
- Adivinhe os próximos movimentos. Faça um palpite (de coordenadas e cores) para o (s) próximo (s) movimento (s) da maneira que desejar. No entanto, a suposição não deve fazer referência à imagem de origem.
- Aplique o palpite. Aplique o pincel na pintura para fazer o (s) movimento (s).
- Meça o benefício do (s) movimento (s). Fazendo referência à imagem de origem, determine se os movimentos beneficiaram a pintura (ou seja, a pintura se parece mais com a imagem de origem). Se for benéfico, mantenha o (s) movimento (s), caso contrário, descarte o (s) movimento (s).
- Repita até a convergência. Vá para a Etapa 1 e tente a próxima tentativa até que o algoritmo tenha convergido o suficiente. A pintura deve se parecer muito com a imagem de origem neste momento.
Se o seu programa não corresponder a essas quatro etapas, provavelmente não é uma subida estocástica. Eu marquei isso como um concurso de popularidade porque o objetivo é produzir algoritmos de pintura interessantes com base na paleta de cores e no pincel limitados.
Restrições
- O algoritmo deve ser estocástico de alguma forma.
O próximo palpite não deve ser influenciado pela imagem de origem. Você está adivinhando cada novo movimento e depois checando se isso ajudou ou não. Por exemplo, você não tem permissão para determinar onde colocar o pincel com base nas cores da imagem de origem (que é semelhante ao pontilhamento da imagem de origem, que não é o objetivo).
Você pode influenciar a veiculação, ajustando as etapas do algoritmo da maneira que desejar. Por exemplo, você pode começar suas suposições pelas bordas e se mover para dentro, arrastar o pincel para criar linhas para cada palpite ou decidir pintar cores escuras primeiro. Você pode fazer referência a imagens de iteração anteriores (mas não a imagem de origem) para calcular o próximo movimento desejado. Elas podem ser restritivas como você deseja (por exemplo, faça apenas suposições no quadrante superior esquerdo para a iteração atual).
A medida da "diferença" entre a imagem de origem e a iteração atual pode ser medida da maneira que você desejar, desde que não calcule outros movimentos em potencial para determinar se esse movimento é considerado o "melhor". Não deve saber se o movimento atual é o "melhor", apenas se ele se enquadra na tolerância dos critérios de aceitação. Por exemplo, pode ser tão simples quanto
abs(src.R - current.R) + abs(src.G - current.G) + abs(src.B - current.B)
para cada pixel afetado ou qualquer uma das técnicas conhecidas de diferença de cores .
Paleta
Você pode baixar a paleta como uma imagem 28x1 ou criá-la diretamente no código.
Escova
O pincel é um quadrado 4x4 sem cantos. Esta é uma versão em escala:
(Seu código deve usar a versão 4x4)
Exemplo
Entrada:
Resultado:
Você pode ver como o algoritmo básico progride em um pequeno vídeo que fiz (cada quadro é de 500 iterações): A Noite Estrelada . Os estágios iniciais são interessantes de se assistir:
fonte
Respostas:
Javascript
Essa solução usa o elemento de tela HTML5 para extrair os dados da imagem, mas sem a necessidade de usar HTML, isso significa que ele pode ser executado no seu console. Ele acessa a imagem da paleta de cores como uma matriz; Guardei todas as cores da imagem da paleta em uma matriz). Ele gera no console (depois que termina) e também armazena o resultado em uma variável.
A versão mais atualizada do código está no violino . O violino também usa um algoritmo melhor para reduzir o ruído nas imagens. A melhoria no algoritmo consiste principalmente na fixação de uma função (máx. A mín.) Que fez com que a cor inversa fosse escolhida.
Código na forma do ícone do MS Paint! (código formatado no violino ou no snippet de pilha)
Uso:
Violino .
O violino usa o crossorigin.me para que você não precise se preocupar com o compartilhamento de recursos entre origens.
Também atualizei o violino para que você possa ajustar alguns valores para produzir a pintura mais bonita. As cores de algumas imagens podem estar desativadas. Para evitar isso, ajuste o accept_rate para ajustar o algoritmo. Um número menor significa melhores gradientes, um número maior resultará em cores mais nítidas.
Aqui está o violino como um snippet de pilha (NÃO atualizado, caso o violino não funcione):
Mostrar snippet de código
Para comemorar o sobrevôo de Plutão da New Horizon, introduzi uma imagem de Plutão:
Para o seguinte, eu o configurei para fazê-los parecer o original o mais próximo possível:
Corri isso com o papel de parede padrão do OS X Yosemite. Depois de deixá-lo rodar um pouco, os resultados são absolutamente impressionantes. O arquivo original era enorme (26 MB), então eu o redimensionei e compactei:
A noite estrelada (usei uma imagem de maior resolução para obter melhores resultados)
Uma foto que encontrei no google:
fonte
JavaScript + HTML
Aleatória:
Ponto aleatório
Alinhado aleatoriamente:
Subdivide a tela em quadrados 4x4 e escolhe um ponto aleatoriamente dentro de um dos quadrados. As compensações moverão a grade, para que você possa preencher as pequenas lacunas.
Ciclo:
Cria uma grade e percorre todos os pontos. Deslocamentos move a grade. O espaçamento determina o tamanho de cada célula. (Eles vão começar a se sobrepor)
Diferença de cor:
RGB:
HSL:
HSV:
fonte
document.cookie
(após 1000 iterações) porque o documento está em área restrita. O cookie é necessário?doThing
vez deloop
. Você pode achar o aumento de velocidade vale a pena a linha extra ...C # (implementação de referência)
Este é o código usado para gerar as imagens na pergunta. Eu pensei que seria útil dar a algumas pessoas uma referência para organizar seu algoritmo. Uma coordenada e cor completamente aleatórias são selecionadas a cada movimento. O desempenho é surpreendentemente bom, considerando as limitações impostas pelos critérios de tamanho / aceitação do pincel.
Eu uso o algoritmo CIEDE2000 para medir diferenças de cores, da biblioteca de código aberto ColorMine . Isso deve fornecer correspondências de cores mais próximas (do ponto de vista humano), mas não parece ser uma diferença perceptível quando usada com esta paleta.
Em seguida, você pode gerar uma série de imagens (como o meu vídeo) chamando uma instância de maneira semelhante ao código abaixo (ajuste com base no número de iterações / quadros / nome desejado). O primeiro argumento é o caminho do arquivo para a imagem de origem, o segundo argumento é o caminho do arquivo para a paleta (vinculada na pergunta) e o terceiro argumento é o caminho do arquivo para as imagens de saída.
Procurei on-line algumas pinturas em tela coloridas e me deparei com as imagens abaixo, que parecem ótimas imagens de teste (complicadas). Todos os direitos autorais pertencem aos seus respectivos proprietários.
Fonte
Fonte
Fonte
fonte
Tela JavaScript
Atualizar
Excelentes sugestões nos comentários. Agora é mais rápido e não diminui a velocidade da interface do usuário!
fonte
Mathematica
Mas não é tão rápido assim, mas pelo menos faz imagens vagamente reconhecíveis, então estou feliz.
Resultado:
A saída provavelmente poderia ser um pouco melhor com mais iterações, e ainda há muito que eu posso tentar acelerar / melhorar a convergência, mas por enquanto isso parece bom o suficiente.
fonte
SmileBASIC
Imagem MSPAINT % [] , largura% , altura% , etapas% OUT OUT % []
fonte