Schlagwort: Programmierpraktikum

  • Radiometrische Beleuchtungssimulation mit präziser Sensormodellierung.

    Von meinem Programmierpraktikum habe ich hier in meinem Blog ja schon so einiges erzählt. Mit diesem Artikel möchte ich nun abschließend meine zusammenfassende Ausarbeitung der Allgemeinheit zur Verfügung stellen.

    Ausarbeitung: zybesi.pdf (360 KB)

    Die erstellte Software selbst, die ich Zybesi getauft habe (Zylinderbeleuchtungssimulator), beziehungsweise deren Quelltext werde ich nicht veröffentlichen. Das hängt damit zusammen, dass Zybesi massiven Gebrauch der FORWISS-Libraries macht. Diese werden für Punkt- und Vektorrechnungen in der Ebene und im Raum sowie für die Erstellung der grafischen Benutzeroberfläche benötigt. Jedoch sind diese Libraries nicht frei zugänglich. Da sie aber sowohl zum Kompilieren als auch für die Ausführung meines Programms benötigt werden, macht es wohl keinen all zu großen Sinn, Quelltext oder das Programm selbst über meinen Blog zu veröffentlichen.

  • Der Pinguin spurtet davon.

    Gestern stand die Abschlusspräsentation meines Programmierpraktikums an, die sehr erfolgreich verlief. In den nächsten Tagen werde ich dann auch die Ausarbeitung meines Programmierpraktikums online stellen.

    Bei der Vorbereitung der Präsentation ist mir noch was aufgefallen, was auch in der Ausarbeitung keine Erwähnung mehr findet. Entwickelt hab ich mein Simulationstool hauptsächlich unter Windows, die Präsentation der Software habe ich jedoch unter Linux gemacht. Dabei ist mir aufgefallen, dass die Erstellung der Simulationsbilder unter Linux (unterer Screenshot) wesentlich weniger Zeit beansprucht als unter Windows (oberer Screenshot), was folgende beiden Screenshots illustrieren sollen.


    Zwar werden die Laufzeiten auf ganze Sekunden abgerundet, aber man sieht, dass die Ausführung unter Windows (oberer Screenshot) sage und schreibe doppelt so lange dauert wie unter Linux (unterer Screenshot). In meinem Fall handelt es sich um die Distribution Ubuntu).

    Dabei wurde beide Male haargenau der selbe Zylinder simuliert mit exakt den selben Form-, Lage-, Beleuchtungs- und Modellierungsparametern. Beide Male wurde die Software mit gcc kompiliert mit absolut identischen Compileroptionen. In keinem der beiden Testläufe waren zusätzliche Programme geöffnet, die Prozessor oder Speicher hätten auslasten können. Auch das Testsystem, mein Notebook, war beide Male das gleiche.

    Zwar handelte es sich bei meiner Windows XP Professional Version um die 32-Bit Variante und bei Ubuntu um die mit 64-Bit Unterstützung, das dürfte aber nur einen Unterschied bei der Genauigkeit der Berechnungen, jedoch nicht bei deren Geschwindigkeit machen. Auch die Tatsache, dass nur die Windows Version das Abspeichern von PNG-Dateien unterstützt, dürfte keinen Unterschied machen, da dieses Abspeichern explizit ausgeführt werden muss und nichts mit dem eigentlichen Bildberechnungsprozess zu tun hat. Da es sich bei der CPU in meinem Notebook (einem AMD Athlon-64 3000+) um eine Singlecore CPU handelt, kann auch eine eventuell betriebssystemabhängige Schleifenparalellisierung (in der aktuellen Version ist Zybesi keine Multithreadanwendung), für die wirklich einiges Potential in meiner Software vorhanden ist, nicht schuld an den massiven Leistungsunterschieden sein. Auch habe ich darauf geachtet, dass die CPU sowohl unter Windows als auch unter Linux auf maximalem Arbeitstakt läuft und sich nicht in irgendeinem Stromspamodus befindet und sich somit automatisch herunter taktet.

    Das soll jetzt natürlich nicht heißen, dass Linux das bessere (oder zumindest schnellere) Betriebssystem ist, aber eine Erwähnung in Form dieses Blogeintrags war’s mir dann doch wert.

    Nachtrag („Wer lesen kann ist klar im Vorteil“ oder „Wikipedia ist (meistens) dein Freund“):
    Jetzt habe ich doch noch die Lösung für den großen Geschwindigkeitsunterschied bei den Berechnungen unter den beiden Betriebssystemen gefunden. Den weitaus größten Teil der Berechnungen in meinem Simulationstool machen Skalarprodukte von Vektoren aus, also im Prinzip Additionen und Multiplikationen von Gleikommazahlen. Bei der AMD64-Architektur, die die x86-Architektur und den x86-Befehlssatz erweitert und über die meine Notebook-CPU verfügt, sind zwei Faktoren entscheidend für den Performanceboost, den ich festgestellt habe.

    • Im 64-Bit Modus stellt die AMD64-Architektur 16 zusätzliche Register zur Verfügung, die bei der Ausführung von 32-Bit Anwendungen auf der selben CPU nicht zugänglich sind.
    • Hauptunterschied für den Geschwindigkeitsunterschied dürfte jedoch sein, dass die AMD64-Architektur für Gleitkommaoperationen nicht auf die x86-FPU zurück greift, sondern stattdessen die entsprechende SSE-Einheit benutzt. Diese ist von Haus aus performanter als die x86-FPU. Größter Vorteil der SSE-Einheit ist die Tatsache, dass deren Register, in denen die Operanden für eine Berechnubg stehen, 128 Bit breit sind. Im Gegensatz dazu sind die Register der x86-FPU nur 80 Bit breit.
      In ein Register der SSE-Einheit passen also vier Gleitkommazahlen einfacher Genauigkeit oder zwei Gleitkommazahlen doppelter Genauigkeit. Der Clou ist nun, dass die SSE-Einheit tatsächlich pro Verarbeitungschritt jeweils zwei Gleitkommazahlen doppelter Genauigkeit aus zwei Registern nehmen kann und so in einem Schritt zwei Gleitkommaberechnungen durchführt. Dies dürfte wohl die doppelte Ausführungsgeschwindigkeit der Bildberechnung unter Linux im 64-Bit Modus erklären.

    Wer das alles mal selbst durchlesen möchste, dem empfehle ich die beiden Wikipedia-Artikel zu AMD64 und SSE, aus denen ich diese Informationen habe.

  • Try & Error.

    Am letzten Sonntag hab ich’s endlich hinter mich gebracht: Mein Programmierpraktikum. Aus diesem Anlass möchte ich gleich zwei Blogeinträge online stellen. Den Ersten gibt’s heute. Teil zwei erscheint dann aller Voraussicht nach die nächsten Tage und wird die Ausarbeitung zu meinem Programmierpraktikum enthalten.

    Heute gibt’s aber erstmal ein bisschen zum „Schmunzeln“. Neben zahlreichen Bugs in meiner Software gab’s auch welche, die sich schön mit Bilder dokumentieren lassen. Schließlich handelt es sich um ein Tool, das die Beleuchtung von Zylindern simuliert und folglich auch Bilder produziert. Da kann so ein Programmierfehler oder eine falsch gesetzte Variable zu Bildern führen, die so nicht ganz dem realitätsnahen Anspruch meiner Software mithalten können. Also los geht’s…


    Das kommt davon, wenn man die Werte seiner Bildpunkte nicht im Blick hat. Dieses Bild ist aufgrund zahlreicher double-Überläufe entstanden. Noch dazu liegt die Lichtquelle der Szene genau hinter dem Zylinder, was eigentlich zu gar keiner Beleuchtung in dem Bereich führen dürfte, der von der Kamera eingesehen werden kann.


    Nanu, was ist denn hier passiert: Die unteren 2/3 sehen ja noch ganz OK aus, aber ab dem Fluchtpunkt sollte da doch nichts mehr sein. Stimmt, das kommt davon, wenn man die Sichtstrahlen des Raytracings zu stiefmütterlich behandelt. Die schneiden den Zylinder natürlich nicht nur vor, sondern auch hinter der Kamera, dort, wo sie eigentlich nichts sehen dürften. Schließlich hat eine Kamera keine Augen auf dem Rücken.


    Arrays hin und her zu kopieren ist eigentlich die Todsünde eines jeden Programmierers. Ab und zu lässt sich das aber nicht ganz vermeiden und wenn man nicht aufpasst, kommen solche tollen Streifen dabei raus.


    Und das passiert wenn man meint, dass sein Simulationsbild einen Pixel breiter und höher ist, als es tatsächlich zutrifft. Dann verschiebt sich beim Zeichnen der mühsam berechneten Pixel jede Zeile und jede Spalte ein wenig und über das ganze Bild betrachtet, sieht das dann so aus.

  • Subpixelgenaue Geometrierekonstruktion auf der Basis lokaler Raummodelle.

    Jetzt nehme ich mir doch mal die Zeit und schreibe ein paar Sätze zu meinem Programmierpraktikum. Das ist nämlich in diesem Semester meine universitäre Hauptbeschäftigung da es sich um den letzten Schein handelt, den ich für die Zulassung zu meinen Diplomprüfungen im Hauptfach, die ich im Spätsommer ablegen will, benötige. In so einem Programmierpraktikum geht es darum in Einzelarbeit im Zeitraum von drei bis sechs Monaten ein größeres Softwareprojekt auf die Beine zu stellen. Ich hatte ja bereits einen Andeutungsblogeintrag verfasst, der Außenstehenden wohl mehr Fragen als Antworten beschert hat. Deshalb hier ein paar ausführlichere Absätze. Werkeln tue ich an diesem Programmierpraktikum, dessen Titel auch gleichzeitig der Titel dieses Blogeintrags ist, schon seit Anfang/Mitte Oktober und ich schau‘, dass ich bis Mitte/Ende Februar alles über die Bühne gebracht habe. Also worum geht’s?

    Bei Qualitätssicherungsprozessen in der Industrie geht es oftmals um die schnelle Vermessung von technischen Bauteilen, also beispielsweise wie groß diese sind, wie sie im Raum liegen oder ob eventuell eine Verschmutzung oder Beschädigung vorliegt. Diese Bauteile sind meistens aus geometrischen Primitiven wie Kugeln, Kegeln, Zylinder, Quader oder dergleichen aufgebaut. Will man also Qualitätssicherung oder Bestimmung der geometrischen Eigenschaften eines technischen Bauteils durchführen, so muss man erstmal diese geometrischen Primitiven in den Griff bekommen.

    Die geometrische Primitive, mit der ich mich in meinem Programmierpraktikum beschäftige ist der Zylinder. Meine Aufgabe dabei lautet anhand eines Bildes, das von einem realen Zylinder (also zum Beispiel einem Draht oder einem Rohr oder der abgerundete Eckteil einer Tischkante) geschossen wurde, die Raum- und Lageparameter (wie Radius und Ausrichtung) des Zylinders zu ermitteln.

    Um diese Aufgabe zu meistern gehe ich wie folgt vor: Ich habe ein reales Foto des Zylinders, den ich vermessen soll sowie Informationen über die Oberflächeneigenschaften des Zylinders wie Rauheit oder Reflektanzeigenschaften. Darüber hinaus stehen mir Informationen über die Anordnung der Kamera, die das reale Foto geschossen hat und die Lichtquelle, die den Zylinder beleuchtet, zur Verfügung. Aus diesen Informationen erstelle ich nun virtuell im Computer ein gerechnetes Bild eines Zylinders, der die selben Oberflächeneigenschaften hat, wie der in der Realität fotografierte und der auf die selbe Weise beleuchtet wird. Da mir jedoch keine Lageinformationen des realen Zylinders zur Verfügung stehen (diese will ich ja bestimmen), entspricht das virtuelle Bild nicht dem geschossenen Foto.

    Der Clou bei der Sache ist nun, dass ich an den Lageparametern des Zylinders (genau handelt es sich dabei um fünf zu ermittelnde Parameter: Radius des Zylinders (ein Parameter), Neigung des Zylinders (zwei Parameter) und Verschiebung des Zylinders in der xy-Ebene (nochmals zwei Parameter)) so lange rumprobiere und herumexperimentiere, bis der Zylinder auf dem virtuell erstellten Bild genau so aussieht wie der Zylinder auf dem geschossenen Foto. Zu diesem Zweck gibt es eine „intelligente“ Art des Ausprobierens, die sich Nichtlineare Optimierung nennt.

    Um das virtuelle Bild zu erstellen brauche ich zum einen ein Modell der Beleuchtung des Zylinders und zum anderen eine Modellierung der Eigenschaften der Kamera, die das reale Bild geschossen hat. Bei ersterem handelt es sich um mehr oder weniger realistische Modelle zur Berechnung der Reflektanzeigenschaften des Zylinders beziehungsweise dessen Verhalten bei unterschiedlicher Beleuchtung. Bei letzterem wird beachtet, dass eine Kamera in der Realität nicht so arbeitet wie ein Raytracer. Näheres will ich an dieser Stelle jedoch nicht erwähnen, denn das würde schon sehr tief ins Detail gehen.

    Ich schau, dass ich, sobald mein Programmierpraktikum abgeschlossen ist, den Quelltext meines Programms und vor allem meine Ausarbeitung, in der die Vorgensweise dann sehr genau beschrieben ist, hier in meinem Blog online stellen kann. Nachdem’s vor ein paar Tagen schon das erste virtuell erstellte Bild in meinem Blog zu bestaunen gab möchte ich an dieser Stelle ein Bild posten, das den aktuellen Stand meiner Arbeit wiederspiegelt. Dabei handelt es sich zwar noch um ein Bild das via Raytracing erstellt wurde, die Kameracharakteristik also noch keine Rolle spielt, das aber schon wesentlich realistischer als mein allererstes Bild aussieht.

  • Durchbruch.

    Nur ganz kurz ein Bild der Früchte meines Erfolgs. Die meisten werden jetzt keine Ahnung haben, was es mit diesem Bild auf sich hat, allen anderen sei gesagt: Bei diesem Bild handelt es sich um das allererste, bei dem’s geklappt hat. Dementsprechend mau sieht’s noch aus.

    Wenn ich in den nächsten Tagen mal ein wenig Zeit hab, wonach’s leider nicht aussieht, werd‘ ich mal ein bisschen mehr über die Hintergründe des Bildes schreiben.