Die Größe des Mondgeheimnisses
Ich bin sicher, Sie haben gehört, dass der Mond seine Größe ändert. Wenn Sie verliebt sind und Glück haben, ist der Mond im Vergleich zu normalen Situationen fast doppelt so groß. Einige Leute sagen, der Grund dafür sei die Atmosphäre, die als Linse fungiert. Andere meinen, es handele sich nur um einen Vergleich mit anderen Objekten wie Bäumen in der Nähe. Welche Erklärung Sie auch lesen, sie ist ziemlich subjektiv.
Die Größe der Mondwissenschaft
Ok, wir sind Programmierer, nicht wahr? Wir verlassen uns auf Fakten, oder? Also hier ist das Experiment:
- Nehmen Sie eine schöne Kamera, die das manuelle Einstellen von Zeit und Blende unterstützt.
- Stellen Sie Ihre Kamera auf die maximale Zoomstufe ein.
- Machen Sie ein paar Fotos vom Mond, um die besten Einstellungen zu ermitteln, damit der Mond scharf ist und die Beleuchtung in Ordnung ist.
- Merken Sie sich die Einstellungen
- Machen Sie mit diesen Einstellungen jedes Mal Fotos vom Mond, wenn Sie glauben, der Mond sei groß oder klein.
- Berechnen Sie die Größe des Mondes in Pixel
Die Kamera lügt doch nicht, oder? Durch Zählen der hellen Pixel können wir die Größe des Mondes effektiv messen - zumindest in Pixel.
Wenn die Größe aller Fotos gleich ist, ist dies ein Fehler in unserem Gehirn. Wenn die Größe unterschiedlich ist, gibt es Raum für Spekulationen
- der Mond wächst wirklich (aber was isst er?)
- Es gibt einen atmosphärischen Linseneffekt
- Der Mond hat eine elliptische Kurve und ist manchmal näher, manchmal weiter von der Erde entfernt
- ...
Aber ich lasse das offen, bis deine Aufgabe erledigt ist. Natürlich möchten Sie im Voraus wissen, ob Ihre Software die Mondgröße genau berechnen kann.
Die Aufgabe
Berechnen Sie anhand einiger optimierter Bilder des Mondes die Größe des Mondes. Die Optimierung ist: Die Pixel sind entweder schwarz oder weiß. Nichts dazwischen. Kein Antialiasing. Das macht es einfach, nicht wahr?
Der Vorbehalt: Der Mond ist nicht immer voll, wissen Sie ... es kann eine Sichel sein! Aber auch in Sichelform ist der Mond größer. Also berechnen Sie bitte die volle Größe.
- Ihr Programm verwendet eine PNG als Eingabe, z. B. als Befehlszeilenargument für Dateinamen, als Pipeline
stdin
oder als Bitmap-Objekt (einer Standard-Framework-Bibliothek), wenn Sie eine Funktion anstelle eines Programms schreiben. - Ihr Programm arbeitet mit einer angemessenen Bitmap-Eingabegröße, die nicht unbedingt quadratisch sein muss. Minimale Breite und Höhe von 150 Pixel sind garantiert.
- Der Vollmond bedeckt mindestens 25% des Bildes.
- Ihr Programm gibt die berechnete Größe des Mondes in Pixeln aus, als wäre es ein Vollmond.
- Wir nehmen an, dass der Mond eine perfekte Kugel ist.
- Die genaue Größe ist immer eine Ganzzahl, aber Sie können eine Dezimalzahl ausgeben, wenn Ihre Berechnung dies ergibt.
- Die Genauigkeit sollte zwischen 98% und 102% liegen. (Das ist eher eine Vermutung als etwas, das ich garantieren könnte, um erreichbar zu sein. Wenn Sie denken, dass es zu schwer zu erreichen ist, hinterlassen Sie bitte einen Kommentar.)
Update :
- Der Mittelpunkt des Mondes muss nicht unbedingt in der Mitte des Bildes liegen.
- Die minimale sichtbare Fläche beträgt 5% des Mondes oder 1,25% der Gesamtzahl der Pixel.
- Das Bild wird so aufgenommen, dass der gesamte Mond zum Bild passt, dh die Gesamtzahl der Pixel ist eine Obergrenze für die Mondgröße.
- Der Mond wird nicht beschnitten.
Die Beispiele
Sie können Ihre eigenen Samples mit der Blend-Datei erzeugen, wenn Sie möchten. Ich habe die folgenden Bilder für Sie erstellt. Sie können Pixel in einer PNG-Datei mithilfe von WhitePixelCounter.exe (benötigt .NET) zählen, um zu überprüfen, ob das Bild nur schwarze und weiße Pixel enthält und wie viele davon.
Die folgenden 256 x 256 Pixel großen Bilder unterscheiden sich in der Anzahl der weißen Pixel, sollten jedoch alle zu einer berechneten Mondgröße von 16416 Pixel führen.
Und diese 177x177 Pixel-Bilder sollten 10241 Pixel zurückgeben. Die Bilder sind grundsätzlich gleich, diesmal wurde jedoch eine Kamera mit einer anderen Brennweite verwendet.
Nicht quadratische und nicht zentrierte Samples mit einem Ergebnis von 9988:
Oh, ich habe momentan keine Referenzimplementierung und ich weiß nicht einmal, ob ich etwas implementieren kann. Aber in meinem Gehirn gibt es einen starken Glauben, der mir sagt, dass es mathematisch lösbar sein muss.
Die Regeln
Das ist Code Golf. Der kürzeste Code am 30.03.2015 wird akzeptiert.
quelle
Antworten:
Mathematica
126 119109 BytesMathematica kann die Dehnung einer Komponente in einem Bild messen. Ein Vollmond, der perfekt symmetrisch ist, hat eine Dehnung von 0 auf einer Skala von 0 bis 1.
Ein abnehmender Mond wird zunehmend länglicher und erreicht ein Maximum von ungefähr 0,8.
0.998 -0.788 x-0.578 x^2
war das empirisch ermittelte Modell (basierend auf den großen Fotos) zur Vorhersage der Fülle des Mondes (nach Fläche) aufgrund seiner Ausdehnung.Ich habe das Modell
1- 0.788 x -0.578 x^2
so angepasst, dass das Modell bei genau null Dehnung (Vollmond) 1 für den Pixel-Skalierungsfaktor zurückgibt. Es spart 4 Bytes und bleibt dennoch innerhalb der Genauigkeitsgrenzen.Dieses Modell wird für Bilder jeder Größe verwendet. Das Mondbild muss nicht zentriert sein. Es muss auch keinen festen Anteil des Fotos bedecken.
Hier sind die Datenpunkte (Dehnung, angezeigte Mondpixel / volle Mondpixel) für die großen Bilder und das Parabolmodell, die für die Daten generiert wurden. Lineare Modelle passen in Ordnung, aber das quadratische Modell ist in Grenzen tot (siehe unten).
Hier sind die Daten aus den großen Bildern. So ist das Modell
Unten sind die Daten (die roten Punkte) von den kleinen Bildern. Das Modell (die blaue Kurve) wird aus den großen Bildern wie oben dargestellt erzeugt.
Der kleinste Halbmond hat 7,5% der Fläche eines Vollmonds. (Der kleinste Halbmond unter den großen Fotos ist 19% eines Vollmonds.) Wenn das quadratische Modell auf den kleinen Fotos basiert hätte, wäre die Passform darunter besser, nur weil sie den kleinen Halbmond aufnimmt. Ein robustes Modell, das unter einer Vielzahl von Bedingungen standhält, einschließlich sehr kleiner Halbmonde, sollte besser aus einer größeren Vielfalt von Bildern hergestellt werden.
Die Passgenauigkeit zeigt, dass das Modell für die angegebenen Bilder nicht fest codiert war. Wir können ziemlich sicher sein, dass die Ausdehnung eines Mondes unabhängig von der Größe des Fotos ist, wie man es erwarten würde.
f
Nimmt das Bildi
als Eingabe und gibt die vorhergesagte Größe des Vollmonds in Pixeln aus. Dies funktioniert bei Aufnahmen außerhalb der Bildmitte.Wie die Daten unten zeigen, sind es alle Testfälle bis auf einen. Die Monde waren von voll bis sehr verkleinert angeordnet.
Ein Foto kann mehr als eine Bildkomponente enthalten. Sogar ein einzelnes Pixel, das von den anderen getrennt ist, wird als eindeutige Komponente betrachtet. Aus diesem Grund ist es notwendig, "alle" Komponenten zu durchsuchen, um die zu finden, die die größere Anzahl von Pixeln aufweist. (Eines der kleinen Fotos hat mehr als eine Bildkomponente.)
Große Bilder
Die auf den großen Fotos gemachten Vorhersagen der Mondgröße waren gleichmäßig genau.
Kleine bilder
Die auf den kleinen Fotos gemachten Vorhersagen der Mondgröße waren einheitlich, mit einer großen Ausnahme, dem endgültigen Bild. Ich vermute, das Problem rührt von der Tatsache her, dass der Halbmond sehr eng ist.
quelle
i_~c~t_:=Max[#2&@@@i~ComponentMeasurements~t];f@i_:=i~c~"Count"/(1-0.788x-0.578x^2/.x->i~c~"Elongation")
#2&@@@
funktioniert der Vorschlag nichtc
istc=Max@ComponentMeasurements[##][[All,2]]&
J,
227207 Bytes (maximaler Fehler 1,9%)Meine Hauptidee ist, dass wir, wenn wir 3 Punkte auf der Kontur des Mondes finden, die auch auf der Kontur des Vollmonds sind, den Umkreis dieser Punkte berechnen können . Dieser Umkreis ist zum Vollmond.
Wenn wir zwei weiße Punkte mit maximalem Abstand finden, sind dies immer solche Punkte, die entweder eine echte Diagonale im Vollmond oder die Endpunkte des Halbmonds sind.
Wir können das Paar von Punkten mit der größten Entfernung in jedem Diagramm finden, indem wir den Punkt auswählen, der von einem gegebenen Startpunkt am weitesten entfernt ist, und dann den Punkt auswählen, der am weitesten von dem ausgewählten entfernt ist.Wir finden einen dritten Punkt mit einem Maximalwert der Produkte der Entfernungen von den vorhergehenden Punkten. Dies wird immer auf der Kontur und auf der Außenseite eines Halbmonds oder der größeren Seite eines Gibbous sein.
Der Durchmesser des Kreises wird berechnet als die Länge einer Seite geteilt durch den Sinus des entgegengesetzten Winkels.
Die zeitliche Komplexität dieser Methode ist in der Größe des Eingabebildes linear.
Code
Die Funktion erwartet den eingegebenen Dateinamen als Zeichenfolge.
(Eine (etwas) besser lesbare Version finden Sie im Versionsverlauf.)
Code Erklärung
Der zweite Teil der Definition von s erzeugt eine 3-Punkte-Liste:
s ist die Seitenlänge des Dreiecks ABC
Ergebnisse
Der größte Fehler liegt bei 1,9%.
Die Bilder sind in der gleichen Reihenfolge wie in der Frage.
quelle
Matlab
162156 (nicht ganz im aktuellen Fehlerbereich)Erstens: Die Genauigkeit beträgt weniger als 2% für alle außer einem Bild in jeder der beiden Serien, wo sie größer ist (ungefähr 5% und 14%). Mein Ansatz bestand darin, die zwei Pixel des Mondes zu finden, die am weitesten voneinander entfernt sind, und diese dann als Schätzung für den Durchmesser zu verwenden.
Dies sind die Genauigkeitsergebnisse (reltative Abweichung
1 - (predicted size / real size)
)quelle
C # - 617
Diese Lösung funktioniert nicht für alle Bilder, da auf einem der Bilder die Steigung (m) unendlich wird.
Das Prinzip wurde bereits erwähnt:
Der problematische Fall ist dieser, bei dem die Steigung unendlich ist. Sie können das Problem umgehen, indem Sie das Bild um 90 ° drehen oder in einer Codeschleife über die
y
Achse ziehenx
.Die Mindestgenauigkeit beträgt
quelle