O tamanho do mistério da lua
Tenho certeza que você já ouviu falar que a lua muda de tamanho. Quando você está apaixonado e tem sorte, a lua tem quase o dobro do tamanho em comparação com situações normais. Algumas pessoas dizem que o motivo é a atmosfera que age como uma lente. Outros pensam que é apenas uma questão de comparação com outros objetos, como árvores próximas. Seja qual for a explicação que você lê, é bastante subjetiva.
O tamanho da ciência da lua
Ok, somos programadores, não somos? Contamos com fatos, certo? Então, aqui está o experimento:
- Pegue uma boa câmera que suporte a hora e a abertura manualmente.
- Defina sua câmera para o nível máximo de zoom.
- Saia, tire algumas fotografias da lua para detectar as melhores configurações, para que a lua fique nítida e a iluminação esteja ótima.
- Lembre-se das configurações
- Tire fotos da lua com essas configurações sempre que achar que a lua é grande ou pequena.
- Calcular o tamanho da lua em pixels
A câmera não mente, não é? Contando os pixels brilhantes, podemos medir efetivamente o tamanho da lua - pelo menos em pixels.
Se o tamanho é o mesmo em todas as fotos, é um erro no nosso cérebro. Se o tamanho for diferente, haverá espaço para especulações
- a lua realmente cresce (mas o que ela come?)
- há um efeito de lente atmosférica
- a lua tem uma curva elíptica e às vezes está mais próxima, às vezes mais distante da terra
- ...
Mas deixarei isso em aberto até que sua tarefa seja concluída. É claro que você deseja saber com antecedência se o seu software pode calcular o tamanho da lua com precisão.
A tarefa
Dadas algumas fotos otimizadas da lua, calcule o tamanho da lua. A otimização é: os pixels são pretos ou brancos. Nada no meio. Sem antialiasing. Isso facilita, não é?
A ressalva: a lua nem sempre está cheia, você sabe ... pode ser uma foice! Mas mesmo na forma de uma foice, o tamanho da lua é maior. Então, você calculará o tamanho completo, por favor.
- Seu programa usa um PNG como entrada, por exemplo, como argumento da linha de comando do nome do arquivo, canalizado
stdin
ou como um objeto Bitmap (de uma biblioteca de estrutura padrão) se você escrever uma função em vez de um programa. - Seu programa funciona com qualquer tamanho de bitmap de entrada razoável, não necessariamente quadrado. Largura e altura mínimas de 150 pixels são garantidas.
- A lua cheia cobre pelo menos 25% da imagem.
- Seu programa gera o tamanho calculado da lua em pixels como se fosse lua cheia.
- Assumimos que a lua é uma esfera perfeita.
- O tamanho exato é sempre um número inteiro, mas você pode gerar um número decimal se seu cálculo retornar isso.
- A precisão deve estar entre 98% e 102%. (Isso é um palpite do que algo que eu poderia garantir que seja viável. Se você acha que é muito difícil de alcançar, por favor, deixe um comentário.)
Atualização :
- O centro da lua não está necessariamente no meio da imagem.
- A área mínima visível é de 5% da lua ou 1,25% do número total de pixels.
- A foto é tirada de forma que a lua inteira se encaixe na imagem, ou seja, o número total de pixels é um limite superior para o tamanho da lua.
- A lua não será cortada / cortada.
As amostras
Você pode gerar suas próprias amostras usando o arquivo de mistura, se desejar. Eu criei as seguintes imagens para você. Você pode contar pixels em um arquivo PNG usando o WhitePixelCounter.exe (precisa do .NET) para verificar se a imagem contém apenas pixels em preto e branco e quantos deles.
As seguintes imagens de 256x256 pixels diferem na quantidade de pixels brancos, mas devem resultar em um tamanho calculado da lua de 16416 pixels.
E essas imagens de 177x177 pixels devem retornar 10241 pixels. As imagens são basicamente as mesmas, mas desta vez uma câmera com uma distância focal diferente foi usada.
Amostras não quadradas e não centradas, com resultado de 9988:
Por enquanto, não tenho uma implementação de referência e nem sei se consigo implementar alguma coisa. Mas, no meu cérebro, existe uma forte crença que me diz que deve ser matematicamente solucionável.
As regras
Este é o Code Golf. O código mais curto de 30/03/2015 é aceito.
fonte
Respostas:
Mathematica
126 119109 bytesO Mathematica pode medir o alongamento de um componente em uma imagem. Uma lua cheia, sendo perfeitamente simétrica, tem um alongamento de 0, em uma escala de 0 a 1.
Uma lua decrescente se torna cada vez mais alongada, até um máximo de aproximadamente 0,8.
0.998 -0.788 x-0.578 x^2
foi o modelo empiricamente determinado (baseado nas grandes fotos) para `prever a plenitude da lua (por área), dado seu alongamento.Ajustei o modelo para
1- 0.788 x -0.578 x^2
que, com alongamento exatamente zero (lua cheia), o modelo retorne 1 para o fator de escala de pixels. Ele salva 4 bytes e ainda permanece dentro dos limites de precisão.Este modelo é usado para imagens de qualquer tamanho. A imagem da lua não precisa estar centralizada. Também não precisa cobrir uma proporção fixa da foto.
Aqui estão os pontos de dados (alongamento, exibidosMoonPixels / fullMoonPixels) para as imagens grandes e o modelo parabólico que foi gerado para ajustar os dados. Os modelos lineares se encaixam bem, mas o modelo quadrático está morto, dentro de limites (veja abaixo).
Aqui os dados são das imagens grandes. Então é o modelo
Abaixo, os dados (os pontos vermelhos) são das imagens pequenas. O modelo (a curva azul) é o gerado pelas imagens grandes, o mesmo mostrado acima.
O menor crescente tem 7,5% da área da lua cheia. (O menor crescente entre as fotos grandes é de 19% da lua cheia.) Se o modelo quadrático tivesse sido baseado nas fotos pequenas, o ajuste abaixo seria melhor, apenas porque acomodava o pequeno crescente. Um modelo robusto, que resistisse a uma ampla gama de condições, incluindo crescentes muito pequenos, seria melhor elaborado a partir de uma variedade maior de fotos.
A proximidade do ajuste mostra que o modelo não foi codificado para as fotos fornecidas. Podemos estar bastante certos de que o alongamento da lua é independente do tamanho da foto, como seria de esperar.
f
pega a imagemi
,, como entrada e gera o tamanho previsto da lua cheia, em pixels. Funciona para fotos fora do centro.Como mostram os dados abaixo, todos os casos de teste, exceto um. As luas foram organizadas do total para o mais diminuído.
Mais de um componente da imagem pode aparecer em uma foto. Mesmo um único pixel separado dos outros será considerado um componente distinto. Por esse motivo, é necessário pesquisar "todos" os componentes, para encontrar o que possui o maior número de pixels. (Uma das fotos pequenas possui mais de um componente de imagem.)
Imagens grandes
As previsões do tamanho da lua feitas a partir das fotos grandes eram uniformemente precisas.
Imagens pequenas
As previsões do tamanho da lua feitas a partir das pequenas fotos eram uniformes, com uma grande exceção, a imagem final. Suspeito que o problema decorra do fato de o crescente ser muito estreito.
fonte
i_~c~t_:=Max[#2&@@@i~ComponentMeasurements~t];f@i_:=i~c~"Count"/(1-0.788x-0.578x^2/.x->i~c~"Elongation")
#2&@@@
sugestão não funciona #c
éc=Max@ComponentMeasurements[##][[All,2]]&
J,
227207 bytes (erro máximo de 1,9%)Minha idéia principal é que, se pudermos encontrar 3 pontos no contorno da lua, que também estão no contorno da lua cheia, poderemos calcular a circunferência desses pontos. Esse circuncisão será a lua cheia.
Se encontrarmos dois pontos brancos com distância máxima, esses serão sempre esses pontos, pois serão uma diagonal real na lua cheia ou os pontos finais do crescente.
Podemos encontrar o par de pontos com a maior distância em qualquer gráfico, selecionando o ponto mais distante de qualquer ponto inicial e, em seguida, selecionando o ponto mais distante do selecionado.Encontramos um terceiro ponto com um valor máximo dos produtos das distâncias dos pontos anteriores. Isso sempre estará no contorno e no lado externo de um crescente ou no lado maior de um gibbous.
O diâmetro do círculo é calculado como o comprimento de um lado dividido pelo seio do ângulo oposto.
A complexidade de tempo deste método é linear no tamanho da imagem de entrada.
Código
A função espera o nome do arquivo de entrada como uma sequência.
(Para uma versão (pouco) mais legível, verifique o histórico de revisões.)
Explicação do código
a segunda parte da definição de s cria uma lista de 3 pontos:
s são os comprimentos laterais do triângulo ABC
Resultados
O maior erro é de 1,9%.
As imagens estão na mesma ordem que na pergunta.
fonte
Matlab
162156 (não está exatamente na margem de erro atual)Primeiro de tudo: a precisão é inferior a 2% para todas, exceto uma imagem em cada uma das duas séries, onde é maior (cerca de 5% e 14%). Minha abordagem foi encontrar os dois pixels da lua mais afastados um do outro e depois usá-lo como uma estimativa do diâmetro.
Estes são os resultados de precisão (desvio relativo
1 - (predicted size / real size)
)fonte
C # - 617
Esta solução não funciona para todas as imagens, porque em uma das imagens, a inclinação (m) torna-se infinita.
O princípio foi mencionado antes:
O caso problemático é este, onde a inclinação é infinita. É possível solucionar o problema girando a imagem 90 ° ou em código, faça um loop sobre o
y
eixo em vez dex
.A precisão mínima é
fonte