Giotto di Bondone (1266 - 1337) ist zunächst mal eine spätmittelalterlicher Maler, berühmt durch seine zahlreichen Fresken in italienischen Kirchen der Zeit. Er ist der erste, der ein konkretes astronomisches Ereignis, nämlich die sehr auffallende Widerkehr des halleyschen Kometen im Jahre 1301 in einem Fresko festhielt. Ihm zu Ehren wurde die europäische Raumsonde Giotto benannt, die 1986 am Halleyschen Kometen vorbeiflog und letzendlich auch mein Programmierprojekt.
Ich selbst beschäftige mich seit langem mit astronomischer Bildverarbeitung. Im Jahre 1992 begann ich, ein Windowsprogramm zu entwickeln, daß als Experimentierplatform für die Algorithmenentwicklung dient. Zunächst hieß dieses 16-Bit-Kuddelmuddel "PICMAN", aber auf die Idee sind auch viele andere gekommen, die auf diesem Gebiet mit mir dilettieren. Der Namensversuch 2.0 führte dann zu "PICTOR", einem Sternbild, weil so ein Bildviewer aus meiner Diplomarbeit hieß (damals unter Unix auf einem Hilfsbildschirm laufend) Nachdem nun ausgerechnet MEADE auf die Idee kam, ihre viel kritisierte CCD-Kameraserie so zu benennen, habe ich mich dann auf den ersten aller Astro-Künstler besonnen.
Wer sich selbst mit der Bildverarbeitung beschäftigt und
mir bei der Entwicklung über die Schulter schauen möchte, ist
herzlich willkommen, im Quellcode meiner Software zu stöbern und
sich
eventuell für eigene Projekte die eine oder andere Anregung zu
holen.
Für diesen erfahrungsgemäß sehr kleinen Personenkreis
habe
ich das Projekt CCDLIB gestartet, die Algorithmensammlung aus GIOTTO.
|
Zentrales Datenformat, auf das sich alle Bildverarbeitungsroutinen beziehen, ist eine Bilddatenstruktur, die alle Angaben enthält, die das Bildformat betreffen (Höhe und Breite, Dynamik Offsets u.s.w), jedoch keine Beschreibung, was als Motiv im Bild enthalten ist (Datum, Uhrzeit, Wetterangaben u.s.w.) Diese Datenstruktur CCDLIB_PictureparamStruct ist im Headerfile definiert. Geübten Programmieren wird schnell auffallen, daß sie sich sehr an das FITS-Bildformat anlehnt.
Ein Standardpuffer, der durch die Angaben in der Parameterstruktur definiert wird, besteht aus signed short Werten, also stehen 15 Bit für jedes Pixel zur Verfügung. Warum vorzeichenbehaftet, wo es doch negative Helligkeitswerte nich geben kann ? Ganz einfach: Es gibt ja noch das elektronische Rauschen, daß mit der Helligkeit nichts zu tun hat und sehr wohl negative Werte produziert. Zudem macht das "Mitschleppen" von Vorzeichen die Bildverarbeitung vom Computertechnischen her sehr viel effizienter. Und ich keine keine Kamera auf dieser Welt, die tatsächlich mehr als 15 echte Dynamikbits hätte. Denn die untersten Bits sind immer verrauscht oder werden einfach zum Hochskalieren mit Nullen gefüllt. Zur Bildschirmdarstellung des Standardpufferinhalts werden die untersten 7 Bit einfach weggeschnitten und die oberen 8 in ein unsigned char verwandelt, um überhaupt auf unseren Bildschrmen dargestellt zu werden, die allesamt "nur" 256 Graustufen anzeigen können.
Download von ccdlib.zip (45 Kilobyte)
Stand der Algorithmenentwicklung: September 2000
typedef struct
{
long
linelength;
/* Breite des gesamten Bildpuffers in Pixel */
long
columnheight;
/* Hoehe des gesamten Bildpuffers in Pixel */
long
dynamik;
/* Umfang der moeglichen Graustufen */
short bitsperpixel;
/* Bits pro Pixel */
double aspectratio;
/* Verhaeltnis von Pixelbreite/Pixelhoehe (X/Y) */
double
xpixelsize;
/* Breite eines Pixel in Mikrometer */
double
ypixelsize;
/* Breite eines Pixel in Mikrometer */
enum CCDLIB_PixelTypeEnum
pixeltype;
/* Daten-Type eines Pixels */
enum CCDLIB_ColorTypeEnum
colortype;
/* Zugehoerigkeit SW / Farbbild */
enum
CCDLIB_ColorEnum
colorchannel; /* Evtl. Farbkanal */
enum CCDLIB_ProjecionEnum
projectionstyle;
/* Projektionsart */
union
{
unsigned char
ubyte;
short
word;
unsigned short uword;
long
dword;
float
sfloat;
double
lfloat;
}
blankvalue;
/* Grau/Rotwert fuer nicht besetzte Bildpunkte */
union
{
unsigned char
ubyte;
short
word;
unsigned short uword;
long
dword;
float
sfloat;
double
lfloat;
}
gblankvalue;
/* Gruenwert fuer nicht besetzte Bildpunkte */
union
{
unsigned char
ubyte;
short
word;
unsigned short uword;
long
dword;
float
sfloat;
double
lfloat;
}
bblankvalue;
/* Blauwert fuer nicht besetzte Bildpunkte */
union
{
unsigned char
ubyte;
short
word;
unsigned short uword;
long
dword;
float
sfloat;
double
lfloat;
}
greyscale;
/* Grauwertscala in Units pro Graustufe */
union
{
unsigned char
ubyte;
short
word;
unsigned short uword;
long
dword;
float
sfloat;
double
lfloat;
}
greyoffset;
/* Offset fuer Grau-Nullpunkt i.e. 0 */
char pixelunit[ 24 ];
/* Grauwertskaleneinheit */
double xoriginofscale; /*
Nullpunktkoordinate
bez. auf oben links */
double yoriginofscale; /*
Nullpunktkoordinate
bez. auf oben links */
double
xscaledelta;
/* X-Achsenskaleneinheit pro Pixel */
double
yscaledelta;
/* Y-Achsenskaleneinheit pro Pixel */
double xvalatorigin;
/* X-Achsenskaleneinheit beim Nullpunkt */
double yvalatorigin;
/* Y-Achsenskaleneinheit beim Nullpunkt */
char xaxisunit[ 24 ];
/* Skaleneinheit der X-Achse */
char yaxisunit[ 24 ];
/* Skaleneinheit der Y-Achse */
long
serialcount;
/* Bildnummer des Bildes in einer Serie (1-n) */
long
serieslength;
/* Laenge einer Aufnahmeserie */
}
CCDLIB_PictureparamStruct;
Schwarzweiß und Farbe
Die Algorithmen sind allesamt farbfähig, sofern das Sinn macht. Ein Farbbild besteht dabei aus den Anteilen Rot, Grün und blau, wobei jeder Kanal wieder mit 15 Bit Dynamik dargestellt wird, also 45 Bit zur Verfügungs stehen. Um die Konvertierung in Windows-Bitmaps zu erleichtern, kommt zu erst der Blau-, dann der Grün- und zuletzt der Rotanteil pro Pixel. Die verschiedenen Farbkanäle können über die Strukturvariable enum CCDLIB_ColorEnum colorchannel unterschieden werden.
enum CCDLIB_ColorTypeEnum
{
CCDLIB_BlackWhiteColorType,
/* Schwarz-Weiss-Bild */
CCDLIB_RGBColorType,
/* Bild im RGB-Format */
CCDLIB_HSIColorType,
/* Hue/Saturation/Intensity-Format */
CCDLIB_YUVColorType,
/* Luminanz (Y)/Chrominanz (U,V) Format */
CCDLIB_NumvaluesNoColorType
/* Daten sind keine Bilddaten */
};
enum CCDLIB_ColorEnum
{
CCDLIB_BlackWhiteColor,
/* Schwarz-Weiss */
CCDLIB_RGBChannelColor,
/* RGB-Farbbild */
CCDLIB_RedColor,
/* Rotanteil */
CCDLIB_GreenColor,
/* Gruenanteil */
CCDLIB_BlueColor,
/* Blauanteil */
CCDLIB_HueColor,
/* Farbtoenung */
CCDLIB_SaturationColor,
/* Farbsaettigung */
CCDLIB_IntensityColor,
/* Intensitaet */
CCDLIB_LuminanceColor,
/* Luminanzsignal */
CCDLIB_U_ChrominanceColor,
/* Chrominanz U-Vektor */
CCDLIB_V_ChrominanceColor,
/* Chrominanz V-Vektor */
CCDLIB_NumvaluesNoColor,
/* Daten sind keine Bilddaten */
CCDLIB_EmptyColor
/* Bild hat keinen Inhalt */
};
Die Algorithmen zur Bildaddition
Wer Spaß an Quelltexten hat, möge sich die aktuelle Version von ccdlib.c und ccdlib.h downloaden und mit einem Editor anschauen, für eine Homepage wäre das zu umfangreich. Im weiteren werden aber die einzelnen Routinen beschrieben, die zur Bildaddition vorhanden sind.
Allen Routinen sind einige Übergabeparameter gleich: *pictureparam ist ein Pointer auf die Bildparameterstruktur, wio das Format der Bilder abgespeichert ist. Es ist klar, daß alle aufzuaddierenden Bilder vom gleichen Format sein müssen. *picture zeigt auf einen Puffer, in dem die Werte für die Pixel abgelegt sind. Der Puffer muß initialisiert und groß genug sein.
CCDLIB_AddPictures addiert einzelne Rohbilder in einen Additionspuffer unter Berücksichtigung einer eventuellen Verschiebung und Verdrehung. In *sourcepicrect werden die Koordinaten für einen Ausschnitt übergeben, so daß man auch nur Teile von einem Bild aufaddieren kann. Das braucht man zum Beispiel, um eine Datumsanzeige im Videobild wegzuschneiden. In *destpicpos wird die Koordinate der obersten linken Ecke im Quellbild (i.e. 0,0) im Additionspuffer angegeben und so die Zentrierung realisiert. Bevor das erste Bild addiert wird, muß piccount auf 0 stehen, um den additionspuffer zu initialisieren.
Diese Funktion kann maximal 65536 Bilder aufaddieren, ehe es zu einem Überlauf kommt.
enum CCDLIB_ErrorEnum CCDLIB_AddPictures
(
CCDLIB_RectangleStruct *
sourcepicrect,
double sourcepicangle,
CCDLIB_PositionStruct
* destpicpos,
CCDLIB_PictureparamStruct *
pictureparam,
short * picture,
long * addpuffer,
long piccount );
CCDLIB_MoveAddfieldToPicture formt den Additionspuffer *addpuffer wieder in einen Standardpuffer um, der dann zur Anzeige gebracht werden kann.
enum CCDLIB_ErrorEnum
CCDLIB_MoveAddfieldToPicture
(
CCDLIB_RectangleStruct *
picturerect,
CCDLIB_PictureparamStruct *
pictureparam,
short * picture,
long * addpuffer,
long piccount );
CCDLIB_GetCenterOfDisk ist der Algorithmus, der nach der FWHM-Methode den geometrischen Mittelpunkt einer Planetenscheibe zum Zentrieren sucht. Wichtig ist, daß der Planet im Bild das hellste Objekt ist. Bei diesem Algorithmus kann der Suchbereich mit *picturerect begrenzt werden. Das Ergebnis wird von der Struktur *centercoord geliefert.
enum CCDLIB_ErrorEnum
CCDLIB_GetCenterOfDisk
(
CCDLIB_RectangleStruct *
picturerect,
CCDLIB_PictureparamStruct *
pictureparam,
short * picture,
CCDLIB_PositionStruct
*centercoord
);
CCDLIB_GetCenterOfBrightness ist der Algorithmus, der einen Schwerpunkt der Helligkeit im Suchrechteck *picturerect zum Zentrieren sucht. Wichtig ist auch hier, daß der Planet im Bild das hellste Objekt ist. Das Ergebnis wird von der Struktur *centercoord geliefert.
enum CCDLIB_ErrorEnum
CCDLIB_GetCenterOfBrightness
(
CCDLIB_RectangleStruct *
picturerect,
CCDLIB_PictureparamStruct *
pictureparam,
double threshold,
short * picture,
CCDLIB_PositionStruct
*centercoord
);
CCDLIB_2DCrossCorrelation ist der Algorithmus, der Bilder mit echter Kreuzkorrelation zentriert. Dazu muß vorher ein kleiner, aber auffallender Bildausschnitt mit dem Maßen in *fitsize und den Grauwerten (auch hier signed short) in *fitpuffer übergeben werden. Im Suchrechteck *searchrect wird nun dieses Paßmuster verschoben und bei jeder Pixelposition mit dem darunter liegenden Bild verglichen. Die Koordinate, wo die Korrelation am größten ist, wird als Paßposition genommen. Das Ergebnis wird von der Struktur *centercoord geliefert. Zur Überprüfung der Qualität wird zusätzlich der Korrelationskoeffizient zurückgeliefert, der über 0,8 für gute Überseinstimmung liegen sollte.
enum CCDLIB_ErrorEnum
CCDLIB_2DCrossCorrelation
(
CCDLIB_RectangleStruct *
searchrect,
CCDLIB_RectsizeStruct
* fitsize,
CCDLIB_PictureparamStruct *
pictureparam,
short * picture,
short * fitpuffer,
CCDLIB_PositionStruct
*centercoord,
double * correlation );
Sie dürfen ohne Benachrichtigung des Autors frei kopiert und für nichtkomerzielle Zwecke, wie Aus- und Weiterbildung, Forschung und Lehre, privater Nutzung verwendet werden, nicht jedoch zum Geldverdienen. Eine Übernahme in andere Homepages ist zwar kein Copyrightverstoß, wird aber nicht gerne gesehen, da sich die Quelltexte in einer permanenten Entwicklung befinden und der Autor gerne die Kontrolle über die Inhalte behalten möchte.
Die veröffentlichten Quelltexte sind ausdrücklich Public Domain und dürfen verändert, erweitert und korrigiert werden, sofern es dem technischen und wissenschaftlichen Fortschritt dient. Einzige Auflage ist, wiederum die neu daraus entstandenen Quelltexte zu veröffentlichen. Eine komerzielle Nutzung, auch als Shareware, ist aber untersagt und wird als Verletzung des Copyrights gewertet.
Alle in dieser Website genannten Markennamen und Warenzeichen sind Eigentum ihrer jeweiligen Besitzer.
Eine Garantie für die Funktionsfähigkeit
der
Verfahren, Arbeitstechniken und Algorithmen sowie die unbedingte
Portabilität
und Compilierbarkeit der Quelltexte kann nicht übernommen werden.
Jegliche Haftung für Folgeschäden wird ausgeschlossen. Wegen
des experimetellen Charakters der Videoastronomie und des
GIOTTO-Projektes
bin ich aber für Hinweise, Ergänzungen, Korrekturen und
Kritik
immer sehr dankbar, denn nur mit dem freundlichen Feedback kann so eine
Arbeit zu einem Erfolg für alle (dank der Public Domain Idee)
werden.
|
Ich bin nicht der erste, der sich mit der Verwendung von gewöhnlicher Videotechnik in der Astronomie beschäftigt. Eine weitere, schon viel weiter entwickelte Technik wird zur Beobachtung von Meteoren eingesetzt.
Es gibt gleich drei weitere Einzelentwickler, die sich mit Videoastronomie beschäftigen:
Jürgen Liesmann, mit seinem
unter JAVA laufenden Bildverarbeitungsprojekt Astro-BV,
Stefan Ziegenbalg , der eine
LINUX-basierte
Softwaresammlung (zur Not auch unter DOS) entwickelt und
Jens Dierks, der mit
einfachem Framegrabbing experiemtiert.
Weiterhin gibt es auch Arbeiten von Sirko Molau, die ganz normale Jupiteraufnahmen zu einer Rotationssequenz weiterverarbeiten.
Die CCDLIB ist von Robert Schwebel in die LINUX-Welt übetragen worden. Download hier ... Hier kann ich leider nicht für die Lauffähigkeit und Funktionalität garantieren, da diese Version ohne mein Zutun von anderen weiterentwickelt wird. Anprechpartner ist hier Robert Schwebel.
Neueste Version vom 17. September 2000. Diese Seite
wurde
mal seit dem 14. 6. 1998 aufgerufen
Diese Website und das GIOTTO-Projekt werden gesponsort von Dittié Thermografie