La taille du mystère lunaire
Je suis sûr que vous avez entendu que la lune change de taille. Lorsque vous êtes amoureux et que vous avez de la chance, la lune a presque deux fois sa taille par rapport aux situations normales. Certaines personnes disent que la raison en est l'atmosphère qui agit comme une lentille. D'autres pensent que ce n'est qu'une question de comparaison avec d'autres objets tels que les arbres à proximité. Quelle que soit l'explication que vous lisez, c'est assez subjectif.
La taille de la science de la lune
Ok, nous sommes programmeurs, n'est-ce pas? Nous nous appuyons sur des faits, non? Voici donc l'expérience:
- Prenez un bel appareil photo qui prend en charge le réglage de l'heure et de l'ouverture manuellement.
- Réglez votre appareil photo au niveau de zoom maximum.
- Sortez, prenez quelques photos de la lune afin de détecter les meilleurs réglages pour que la lune soit nette et que l'éclairage soit très bien.
- Rappelez-vous les paramètres
- Prenez des photos de la lune avec ces paramètres chaque fois que vous pensez que la lune est grande ou petite.
- Calculez la taille de la lune en pixels
La caméra ne mentira pas, n'est-ce pas? En comptant les pixels lumineux, nous pouvons mesurer efficacement la taille de la lune - au moins en pixels.
Si la taille est la même sur toutes les photos, c'est un bug dans notre cerveau. Si la taille diffère, alors il y a place à la spéculation
- la lune grandit vraiment (mais que mange-t-elle?)
- il y a un effet de lentille atmosphérique
- la lune a une courbe elliptique et est parfois plus proche, parfois plus éloignée de la terre
- ...
Mais je vais laisser cela ouvert jusqu'à ce que votre tâche soit terminée. Bien sûr, vous voulez savoir à l'avance si votre logiciel peut calculer avec précision la taille de la lune.
La tâche
Compte tenu de quelques images optimisées de la lune, veuillez calculer la taille de la lune. L'optimisation est la suivante: les pixels sont noirs ou blancs. Rien entre les deux. Pas d'anticrénelage. C'est facile, non?
La mise en garde: la lune n'est pas toujours pleine, vous savez ... ça peut être une faucille! Mais même en forme de faucille, la taille de la lune est plus grande. Vous allez donc calculer la taille réelle, s'il vous plaît.
- Votre programme prend un PNG en entrée, par exemple comme argument de ligne de commande de nom de fichier, canalisé dans
stdin
ou en tant qu'objet Bitmap (d'une bibliothèque de framework standard) si vous écrivez une fonction au lieu d'un programme. - Votre programme fonctionne avec n'importe quelle taille de bitmap d'entrée raisonnable, pas nécessairement carrée. La largeur et la hauteur minimales de 150 pixels sont garanties.
- La pleine lune couvre au moins 25% de l'image.
- Votre programme affiche la taille calculée de la lune en pixels comme s'il s'agissait d'une pleine lune.
- Nous supposons que la lune est une sphère parfaite.
- La taille exacte est toujours un nombre entier, mais vous pouvez sortir un nombre décimal si votre calcul le renvoie.
- La précision doit être comprise entre 98% et 102%. (C'est plutôt une supposition que quelque chose que je pourrais garantir. Si vous pensez que c'est trop difficile à atteindre, veuillez laisser un commentaire.)
Mise à jour :
- Le centre de la lune n'est pas nécessairement au milieu de l'image.
- La zone visible minimale est de 5% de la lune ou 1,25% du nombre total de pixels.
- La photo est prise de manière à ce que la lune entière s'adapte à l'image, c'est-à-dire que le nombre total de pixels est une limite supérieure pour la taille de la lune.
- La lune ne sera pas recadrée / coupée.
Les échantillons
Vous pouvez générer vos propres échantillons en utilisant le fichier de mélange si vous le souhaitez. J'ai créé les images suivantes pour vous. Vous pouvez compter les pixels d'un fichier PNG à l'aide de WhitePixelCounter.exe (nécessite .NET) pour vérifier si l'image ne contient que des pixels noir et blanc et combien d'entre eux.
Les images 256x256 pixels suivantes diffèrent par la quantité de pixels blancs, mais devraient toutes entraîner une taille de lune calculée de 16416 pixels.
Et ces images de 177x177 pixels devraient renvoyer 10241 pixels. Les images sont fondamentalement les mêmes, mais cette fois, un appareil photo avec une distance focale différente a été utilisé.
Échantillons non carrés et non centrés avec un résultat de 9988:
Oh, je n'ai pas d'implémentation de référence pour l'instant et je ne sais même pas si je suis capable d'implémenter quelque chose. Mais dans mon cerveau, il y a une forte croyance qui me dit qu'elle doit être mathématiquement soluble.
Les règles
C'est Code Golf. Le code le plus court du 30/03/2015 est accepté.
la source
Réponses:
Mathematica
126119109octetsMathematica peut mesurer l'allongement d'un composant dans une image. Une pleine lune, parfaitement symétrique, a un allongement de 0, sur une échelle de 0 à 1.
Une lune décroissante s'allonge de plus en plus, jusqu'à un maximum d'environ 0,8.
0.998 -0.788 x-0.578 x^2
était le modèle déterminé empiriquement (basé sur les grandes photos) pour `prédire la plénitude de la lune (par zone), compte tenu de son allongement.J'ai ajusté le modèle pour
1- 0.788 x -0.578 x^2
que, avec un allongement exactement nul (pleine lune), le modèle renvoie 1 pour le facteur d'échelle de pixels. Il enregistre 4 octets et reste dans les limites de précision.Ce modèle est utilisé pour toutes les images de taille. L'image de la lune n'a pas besoin d'être centrée. Il n'a pas non plus besoin de couvrir une proportion fixe de la photo.
Voici les points de données (allongement, affichéMoonPixels / fullMoonPixels) pour les grandes images et le modèle parabolique qui a été généré pour s'adapter aux données. Les modèles linéaires conviennent bien, mais le modèle quadratique est mort, dans certaines limites (voir ci-dessous).
Ici, les données proviennent des grandes images. Le modèle aussi
Ci-dessous, les données (les points rouges) proviennent des petites images. Le modèle (la courbe bleue) est celui généré par les grandes images, le même que celui affiché ci-dessus.
Le plus petit croissant a 7,5% de l'aire d'une pleine lune. (Le plus petit croissant parmi les grandes photos est de 19% d'une pleine lune.) Si le modèle quadratique avait été basé sur les petites photos, l'ajustement ci-dessous serait meilleur, uniquement parce qu'il accueillait le petit croissant. Un modèle robuste, qui résisterait dans un large éventail de conditions, y compris de très petits croissants, serait mieux fabriqué à partir d'une plus grande variété d'images.
La proximité de l'ajustement montre que le modèle n'était pas codé en dur pour les images données. Nous pouvons être assez certains que l'allongement d'une lune est indépendant de la taille de la photo, comme on pourrait s'y attendre.
f
prend l'image,i
en entrée et sort la taille prévue de la pleine lune, en pixels. Cela fonctionne pour les prises de vue décentrées.Comme le montrent les données ci-dessous, il s'agit de tous les cas de test sauf un. Les lunes étaient disposées du plus complet au plus diminué.
Plusieurs composants d'image peuvent apparaître sur une photo. Même un seul pixel séparé des autres sera considéré comme un composant distinct. Pour cette raison, il est nécessaire de rechercher "tous" les composants, pour trouver celui qui a le plus grand nombre de pixels. (L'une des petites photos comporte plusieurs composants d'image.)
Grandes images
Les prédictions de la taille de la lune faites à partir des grandes photos étaient uniformément précises.
Petites images
Les prédictions de la taille de la lune à partir des petites photos étaient uniformes, à une grande exception près, l'image finale. Je soupçonne que le problème vient du fait que le croissant est très étroit.
la source
i_~c~t_:=Max[#2&@@@i~ComponentMeasurements~t];f@i_:=i~c~"Count"/(1-0.788x-0.578x^2/.x->i~c~"Elongation")
#2&@@@
suggestion ne fonctionne pasc
estc=Max@ComponentMeasurements[##][[All,2]]&
J,
227207octets (erreur maximale 1,9%)Mon idée principale est que si nous pouvons trouver 3 points sur le contour de la lune qui se trouvent également sur le contour de la pleine lune, nous pouvons calculer le cercle circonscrit de ces points. Ce cercle sera à la pleine lune.
Si nous trouvons deux points blancs avec une distance maximale, ce seront toujours des points tels qu'ils seront soit une vraie diagonale à la pleine lune, soit les extrémités du croissant.
Nous pouvons trouver la paire de points avec la plus grande distance dans n'importe quel graphique en sélectionnant le point le plus éloigné d'un point de départ donné, puis en sélectionnant le point le plus éloigné du point sélectionné.On retrouve un troisième point avec une valeur maximale des produits des distances aux points précédents. Ce sera toujours sur le contour et sur le côté extérieur d'un croissant ou le plus grand côté d'un gibbeux.
Le diamètre du cercle circonscrit est calculé comme la longueur d'un côté divisée par le sinus de l'angle opposé.
La complexité temporelle de cette méthode est linéaire dans la taille de l'image d'entrée.
Code
La fonction attend le nom de fichier d'entrée sous forme de chaîne.
(Pour une version (un peu) plus lisible, consultez l'historique des révisions.)
Explication du code
la deuxième partie de la définition de s crée une liste en 3 points:
s est la longueur des côtés du triangle ABC
Résultats
La plus grande erreur est de 1,9%.
Les images sont dans le même ordre que dans la question.
la source
Matlab
162156 (pas tout à fait dans la marge d'erreur actuelle)Tout d'abord: la précision est inférieure à 2% pour toutes les images sauf une dans chacune des deux séries, où elle est supérieure (environ 5% et 14%). Mon approche consistait à trouver les deux pixels de la lune les plus éloignés l'un de l'autre, puis à les utiliser comme estimation du diamètre.
Ce sont les résultats de précision (écart relatif
1 - (predicted size / real size)
)la source
C # - 617
Cette solution ne fonctionne pas pour toutes les images, car sur l'une des images, la pente (m) devient infinie.
Le principe a été mentionné précédemment:
Le cas problématique est celui-ci, où la pente est infinie. Il est possible de contourner ce problème en faisant pivoter l'image de 90 ° ou en code, en boucle sur l'
y
axe au lieu dex
.La précision minimale est
la source