Usando Algodoo e Paint, fiz essas seis imagens monocromáticas 300 × 300 de quatro formas convenientes:
Esta classe de imagens possui as seguintes propriedades:
- Eles sempre são 300 × 300 pixels, monocromáticos (somente preto e branco) e têm exatamente quatro regiões brancas que correspondem a um quadrado, um círculo, um triângulo e uma engrenagem.
- As formas nunca se sobrepõem ou se tocam, nem tocam a borda da imagem ou ficam fora dos limites.
- As formas sempre têm o mesmo tamanho, mas podem ser giradas e posicionadas de qualquer maneira.
(As formas também têm áreas iguais, embora, quando rasterizadas dessa maneira, é improvável que a contagem de pixels seja exatamente equivalente.)
Desafio
Escreva o programa ou a função mais curta possível que capte o nome do arquivo dessa imagem e gire todos os pixels brancos ...
- vermelho
(255, 0, 0)
se estiverem na praça. - azul
(0, 0, 255)
se estiverem no círculo. - verde
(0, 255, 0)
se estiverem no triângulo. - amarelo
(255, 255, 0)
se estiverem na engrenagem.
por exemplo
Detalhes
Seu programa deve funcionar para efetivamente todas as imagens de entrada possíveis. (Somente imagens monocromáticas válidas de 300 × 300 serão inseridas.) As seis imagens que forneci são meramente exemplos. Você pode não codificar sua saída em seu programa.
Você não pode usar bibliotecas ou funções de visão computacional, internas ou externas. O objetivo é fazer isso usando suas próprias operações em nível de pixel. Você pode usar bibliotecas de imagens que simplesmente permitem abrir e modificar imagens (por exemplo, PIL para Python).
Você pode usar qualquer formato de arquivo de imagem sem perda comum para entrada e saída, desde que se atenha ao esquema de cores.
Você pode observar o nome do arquivo da imagem como argumento de função, de stdin ou da linha de comando. A imagem de saída pode ser salva em um novo arquivo, no mesmo arquivo ou simplesmente exibida.
Pontuação
O envio com o menor número de bytes vence. Posso testar envios com imagens adicionais para determinar sua validade.
fonte
Respostas:
J -
246.224185 bytesEssa foi engraçada!
Reutilizei a parte de componentes conectados que usei para o desafio "Estou na sala maior" e usei a razão entre a distância média e máxima de todos os pontos do centro de cada componente. Eu me conformei com isso, já que a escala e a rotação são invariantes, e aparentemente boas o suficiente para distinguir as formas dadas. Classificar esse valor de baixo para alto me fornece o círculo, a engrenagem, o quadrado e o triângulo da ordem, usados para permutar o mapa de cores.
Exibe o resultado usando o complemento viewmap. Nenhuma caixa de ferramentas usada, exceto para leitura e saída de arquivos.
A robustez não parece ser um requisito, isso tira 18 bytes. Mais 2 espaços desnecessários, substituídos
&.>
por&>
inratio
e&.:
por&:
no dcent por mais 2 bytes.Ganho enorme na falta e no desempenho de
comp
usar shift em vez decut
(;.
). Dessa forma, a imagem é replicada e deslocada nas 8 direções, em vez de digitalizá-la com uma janela 3x3.A
id
função era ridiculamente complexa para o que precisava fazer. Agora, ele atribui IDs a pixels em objetos, multiplicando a imagem com uma matriz de números únicos, configurando o BG para zero.Código um pouco mais explicado:
Este é um pouco longo para explicar em detalhes, mas será útil se houver interesse.
fonte
Mathematica,
459392 bytesUngolfed:
Eu poderia economizar mais 6 bytes transformando
m=1.Mean@a;m=#-m&/@a;
emm=#-Mean@a&/@a;
, mas isso aumenta significativamente o tempo de execução, o que é irritante para o teste. (Observe que são duas otimizações: retirar o cálculo deMean@a
fora de loop e usar tipos simbólicos exatos em vez de números de ponto flutuante. Curiosamente, o uso de tipos exatos é muito mais significativo do que calcular a média em todas as iterações.)Portanto, esta é a abordagem número três:
Agora, para todos os pixels na forma, vamos traçar a distância do ângulo x ao centro:
O triângulo tem 3 máximos nítidos, o quadrado 4, a engrenagem 16 e o círculo possui toneladas, devido a flutuações de aliasing sobre o raio constante.
150
é o máximo.Só para constar, se eu usar a idéia de Ell e simplesmente classificar as regiões pela maior distância entre qualquer pixel e centro, posso fazer isso em 342 bytes:
Mas não pretendo competir com isso, desde que todos os outros usem seus próprios algoritmos originais, em vez de usar os dos outros.
fonte
Java,
1204113210871076Só para provar a mim mesmo que eu posso fazer isso.
Incluí importações ao lado das declarações de função; estes teriam que estar fora da classe para que isso funcionasse:
Ungolfed (e executável; ou seja, clichê adicionado):
Isso funciona iterando sobre cada pixel da imagem e preenchendo cada inundação cada vez que atingimos um "buraco". Adicionamos cada resultado de preenchimento como a
Set<Point>
a aSet
. Então determinamos qual forma é qual. Isso é feito observando o número de pixels de limite da forma. Eu defini limite como o afastamento de um cavaleiro de um ladrilho preto, pois isso permaneceria mais constante entre as rotações e tal. Quando fazemos isso, fica claro que as formas podem ser classificadas por esse valor: Círculo, Quadrado, Triângulo, Engrenagem. Então, ordeno e defino todos os pixels dessa forma para a cor correta.Observe que a imagem para a qual estou escrevendo não é extraída diretamente do arquivo, porque se eu fizesse isso, Java trataria a imagem como preto e branco e o preenchimento de cores não funcionaria. Então eu tenho que criar minha própria imagem com
TYPE_INT_RGB
(o que é1
). Observe também que a imagem na qual estou trabalhando é feita302
por302
; isso é para que o algoritmo de distância de Knight não precise se preocupar em tentar ler fora dos limites da imagem. Corrijo essa discrepância de tamanho ligandoi.getSubImage(1,1,300,300)
. Nota: Talvez eu tenha esquecido de corrigir isso quando carreguei as imagens. Nesse caso, as imagens têm 2 pixels de largura demais, mas, exceto por esse fato, elas devem estar corretasA função substituirá o arquivo cujo caminho é passado. Saídas:
fonte
Pitão,
571 567528 bytesDa mesma forma que a solução de Quincunx, ela começa preenchendo cada forma com um índice de 1 a 4. Em seguida, determina a identidade das formas pelo raio do seu círculo delimitador. Uma paleta de cores é construída de acordo e a imagem é salva como uma imagem de cores indexadas.
Edição: Perdeu o fato de que as formas são garantidas para não tocar na borda da imagem. É mais curto, então!
Pega um nome de arquivo de entrada na linha de comando e grava a saída em
o.png
.fonte
Mathematica 225
Atualização :
O OP decidiu que essa abordagem usa funções de visão computacional, portanto não está mais em execução. Vou deixá-lo publicado no entanto. Talvez alguém possa achar interessante.
ImageData
retorna a imagem como uma matriz de 0 e 1.Flatten
converte essa matriz em uma lista.Morphological Components
localiza os 4 grupos de pixels e atribui um número inteiro distinto, 1, 2, 3, 4 a cada pixel, de acordo com o cluster. 0 é reservado para o plano de fundo (preto).ComponentMeasurements
testa a circularidade dos clusters.Do mais para o menos circular sempre será: o círculo, o quadrado, o triângulo e a engrenagem.
ReplacePart
substitui cada número inteiro do componente pela respectiva cor RGB, usando a classificação de circularidade.Partition...Dimensions[m][[2]]
pega a lista de cores de pixel e retorna uma matriz com as mesmas dimensões da imagem de entrada.Image
converte a matriz de cores de pixel em uma imagem colorida.fonte
f@i_:=Image[#/.Append[Thread[Ordering[Last/@ComponentMeasurements[#,"Circularity"]]->{Yellow,Green,Red,Blue}],0->Black]]&@MorphologicalComponents@i
{RGBColor[1, 0, 0], RGBColor[0, 1, 0], RGBColor[0, 0, 1], RGBColor[1, 1, 0]}
que 1 corresponde a 255. Nenhuma biblioteca foi usada.MorphologicalComponents
satisfaz ou viola suas regras. Quando se sabe a qual cluster cada pixel pertence, existem várias maneiras, incluindo uma contagem bruta de pixels, para determinar qual número é qual.(255,0,22)
quando eu verifico no Paint). Eu não tenho o Mathematica, então não posso correr para ter certeza.Mathematica,
354345314291288Ainda jogando golfe, poderia ser reduzido por mais alguns caracteres, mas o desempenho se torna insuportável. Usa a variação para identificar formas:
Com espaçamento:
Testando:
Aqui é completamente não-destruído. Adicionará explicações mais tarde:
fonte
Python,
579577554514502501 bytesPara cada forma, preencha-a e calcule a distância entre o centróide e o ponto mais distante.
então a superfície real da forma é comparada à superfície de um triângulo, quadrado, disco ou roda que teria o mesmo tamanho.
fonte
Bytes em C # 1086
Mais uma solução de inundação, apenas para constar, já que não há versão C # aqui. Como Quincunx, eu queria provar a mim mesmo que posso fazer isso e não há muita diferença em sua abordagem em Java.
Aceita todos os formatos de imagem.
Provavelmente, pode ser retirado alguns caracteres, removendo todo o material estático e criando uma instância do Program.
Versão legível:
Golfe:
fonte