PHP Maximum im 3D Koordinatensystem

lordg2009

Lt. Commander
Registriert
Apr. 2009
Beiträge
1.552
Hi,

die Frage ist wahrscheinlich eher mathematischer Natur. Aber die Programmierer haben hier im Recht pfiffige Antworten gegeben.

Ich habe 10.000 Werte Triplets x, y, z. Dabei stehen x und y für eine Koordinate zwischen 1 und 100, wobei jede Kombination einmal vorhanden ist. z steht für die Höhe und ist variabel. Würde man die Daten in einem 3D Koordinatensystem abbilden, würde man eine 3D Fläche erhalten mit einem Berg irgendwo um die Mitte.

Beispiel der Daten
1,1,0.5
1,2,0.6
1,3,0.55
...
3,27,1.5
3,28,1.55
3,29,1.45
...

Jetzt geht es darum das Maximum an der Koordinate zu finden, wo der Gipfel des Berges liegt. Den höchsten z-Wert kann ich nicht einfach nehmen, weil kleine Ausreißer am Rand (die ggf. höher sind als der Gipfel des breiten Berges) nicht beachtet werden sollen. Es soll im Prinzip der Gipfel des breitesten Berges ermittelt werden.

Habt ihr eine Idee? Habt ihr verstanden, Wasser ich will?

PS: Programmieren möchte ich mit php
 
Das klingt ziemlich problemspezifisch, weshalb man dir hier vermutlich nur ein paar Denkanstöße geben kann.

Eine Möglichkeit, die mir jetzt so auf die schnell einfällt:
Ermittle für jeden Punkt einen Fitnesswert. Dieser Fitnesswert setzt sich zusammen aus der Summe der Z-Werte aller Punkte. Allerdings werden die Z-Werte der einzelnen Punkte nach ihrem Abstand zu dem zu prüfenden Punkt gewichtet.
Damit erhält jeder Punkt einen Fitnesswert, der höher ist, wenn die Punkte in der Nähe des zu prüfenden Punkts auch hohe Z-Werte haben.
 
Manchmal ist die einfachste auch die beste Lösung, und die hast du dir evtl. schon selbst gegeben:
lordg2009 schrieb:
Rand [...] nicht beachten
 
Es ist nicht sicher, dass der breite Berg in der Mitte sitzt. Deshalb geht Rand entfernen nicht. Fitneswerte klingt spannend. So werde ich es machen. Ich überlege nur noch, ob ich die Punkte linear, oder exponentiell nach außen abfallen lasse.
 
Zuletzt bearbeitet:
lordg2009 schrieb:
Ich überlege nur noch, ob ich die Punkte linear, oder exponentiell nach außen abfallen lasse.

Spontan würde ich expotentiell sagen. Aber sowohl die Funktion, als auch deren Parametrierung musst du einfach ausprobieren.
 
lordg2009 schrieb:
Habt ihr eine Idee? Habt ihr verstanden, Wasser ich will?


  1. Vorbereitung: Startwert ausdenken, der mit Sicherheit niedriger als der Berg ist, z. B. "0.2"
  2. alle z-Werte -0.2 rechnen, alles was kleiner 0 wird, auch 0 setzen
  3. Pass:
    • bei allen 100x100 Koordinaten zählen, wie viele Nachbarn 0 sind (in neuem Hilfs-Array)
    • Deletion: alle Koordinaten, die nach dem Pass mehr oder gleich zwei Hits beim Pass bekommen hatten, 0 setzen
  4. Prüfen, ob mehr als ein zusammenhängender Cluster übriggeblieben ist (visuell oder per Algorithmus)
    • Wenn ja , wieder zu 3.
    • Wenn nein, im Cluster höchsten z-Wert suchen, fertig
 
Zuletzt bearbeitet:
Jo wie NeoExacun schon sagt - man bildet je Punkt einen neuen Wert anhand dessen man dann das Maximum bestimmt.
Um 'schmale' (evtl höhere) Nebenmaxima zu ignorieren macht man üblicherweise eine Glättung. Der 0815 Ansatz wäre hierfür OpenCV. Die besten Parameter für so eine Glättung hängen von der Breite des Berges und der Nebenmaxima an. Sofern der Berg erheblich breiter ist als die Nebenmaxima solltest du auch einen breiten Gauss (hohes Sigma) wählen. In dem neu generierten geglättetem Bild suchst du dann einfach nur das max
Sofern die Daten erstmal in einem cv::mat angekommen sind brauchst du also genau 2 Funktionsaufrufe/Zeilen sourcecode: GaussFilter und minMaxLoc

Dein Problem ist genau das gleiche, wie die Suche nach dem hellsten Fleck in einem Bild wobei einzelne Pixel (Sensoren rauschen nunmal) heller sein können. x,y sind halt die Pixel und dein z wäre Helligkeit im Bild. Daher OpenCV.
 
Zuletzt bearbeitet:
Danke für die Hilfe. Gibt es für JavaScript oder PHP eine Funktion, mit der man die Normalverteilung berechnen kann? Wenn ich danach Suche komme ich immer nur bei Zufallszahlen raus.
 
Zurück
Oben