Depth From Focus 3D-Scanning

In meiner Studienarbeit ging es um die 3D-Rekonstruktion über Schärfentiefe.

Die Daten sollten automatisiert aufgenommen und verarbeitet werden.

Viele Dinge waren für mich Neuland und daher würde ich jetzt wesentlich weniger Zeit zur Umsetzung brauchen und das Ganze besser strukturieren.

Das Bild zeigt grob den geplanten Aufbau.

Hardware Aufbau

Hardware

Zum Aufnehmen stand mir folgendes zur Verfügung:

  • ein Drehteller mit Servomotor
  • eine Linearführung mit Gleichspannungsmotor und Quadraturencoder
  • ein Arduino mit Adafruit Motorplatine zur Steuerung
  • eine Nikon D7000 mit Walimax 85mm f/1.4 (privat)
  • mein Laptop + ein stationärer PC

Arduino mit AdafruitVersuchsaufbau

Software

Um meinen Algorithmus umzusetzen habe ich verschiedene Bibliotheken unter Linux benutzt.

  • Arduino-IDE (Debuggen, Beschreiben Arduino)
  • KDevelop als IDE für das Hauptprogramm
  • libserial (Kommunikation mit dem Arduino)
  • libgphoto2 für die Kamera (Auslösen der Aufnahme, Übertragen der Bilder)
  • libraw (auslesen der .nef)
  • opencv, um die Daten zu verarbeiten
  • libqt4 für die GUI
  • PointCloudLibrary für den Export

Umsetzung

Für die Bedienung habe ich ein Konsolenprogramm und eine Gui geschrieben. Die GUI ist ziemlich grottig, da es meine erste Erfahrung mit Qt war und Aufgrund der knappen zeit auch das Softwaredesign nicht wirklich beachtet wurde. Trotzdem hatte ich viel Zeit reingesteckt, die Einstellungen über xml zu usw.

Das folgende Bild zeigt das graphische Interface. Für die 3 Hauptaufgaben gibt es jeweils einen Reiter mit unterschiedlichen Optionen und dann rechts ein aktuelles Bild.

GUI

Kalibrierung

Als optisches Messsystem muss natürlich als erstes das Objektiv kalibriert werden. Danach muss die Fokusdistanz genau bestimmt werden, da darauf basierend auch die Tiefenberechnung stattfindet. Als drittes muss noch die Fahrtrichtung zum Objekt bestimmt werden. In meinem Fall habe ich das Objektiv mit einem Schachbrett Muster und Open-CV realisiert. Dabei musste ich feststellen, dass OpenCV die Kalibrierung nicht für große Bilder ausgelegt hat und das Finden der Ecken des Schachbrettes hat sehr lang gedauert.

Da die Ecken später eh subpixelgenau angepasst werden, abe ich die Positionen mit 1/4 der Auflösung bestimmt und dann ging es auch entsprechend schnell.

Da ohne bekannte Entfernung die Korrespondierenden Punkte unbekannt sind habe ich für die Distanz und Richtungsbestimmung ebenfalls das Schachbrett genutzt.

Die Distanz habe ich Iterativ mit jeweils 3 Fokusmaßen bestimmt. Angefangen mit großen Fahrtwegen, habe ich immer den Weg halbiert, wenn der größte Fokuswert in der mitte lag. Als Fokusmaß wurde die größte Abweichung zum Mittelwert genutzt.

Die Fahrtrichtung habe ich bestimmt, indem ich aus zwei Aufnahmen die Änderung zum Mittelpunkt bestimmt habe und diese aus mehreren Fällen gemittelt habe.

Verarbeitung

Kamera und Schiene sind jetzt Kalibriert. Jetzt kann bestimmt werden, wie sich das Bild verändern müsste, wenn das Objekt die Fokusentfernung hat. Wenn nicht wird der Objektpunkt unscharf abgebildet und das Fokusmaß ist zu gering. Man hat zu jedem Bildpunkt die Korrespondenzen im Stapel. Da diese sich linear verschieben kann das Bild auch mit möglichst guter Interpolation skaliert werden. Um die Daten möglichst dicht zu halten, habe ich um das Bild mit dem global größten Fokusmaß transformiert.

Video vor Transformation und danach

Verarbeitungsübersicht

Wir sind jetzt im vorletzten Punkt des Verarbeitungsstapels angekommen.

Durch die Transformation liegt jeder korrespondierende Bildpunkt im Stapel hintereinander. Nur dort, wor der Fokus maximal ist, beträgt die entfernung die Fokusdistanz und der Punkt kann zurück transformiert werden.

Durch die Interpolation der Fokuswerte kann die Entfernung noch genauer bestimmt werden.

Da es viel Arbeitsspeicher verbraucht alle Bilder gleichzeitig zu halten, habe ich die Option eingebaut, die Bilder in Clustern zu verarbeiten. Das dauert dann natürlich länger, da die Bilder mehrfach geladen werden müssen.

Aber mein Laptop hatte zum Beispiel zu wenig Arbeitsspeicher.

FokusstackTiefenbild

Neben einem Tiefenbild ist es noch möglich ein Bild zu generieren, wo aus jedem Punkt nur die schärfsten Bildpunkte verwendet werden. Über die PCL habe ich die Pointcloud als ply exportiert. Das kann dann in Meshlab zum Beispiel weiter verarbeitet werden.

Maus FrontalMaus Seite

Falls ihr euch noch weiter für das Thema interessiert :

PLY-Datei der Maus am besten mit Meshlab öffnen

Endpräsentation