Die CCDLIB

- Algorithmensammlung im Quelltext zur Videotechnik in der Astronomie -

[ Das GIOTTO-Projekt | Downloads | Datenstrukturen | Bildaddition  ]
[ Andere Websites zum Thema | Copyright und Disclaimer ]
  E-Mail mit Feedback bitte an Georg Dittié


Das GIOTTO-Projekt

GIOTTO ist ein experimentelles Bildverarbeitungsprogramm, dessen eigentliche Bildverarbeitungs-Algorithmen bei Einsatztauglichkeit auch im Quelltext veroeffentlicht werden sollen. Zur Zeit läuft es unter Win32, also Windows 95 und NT (mit etwas Quietschen und Hakeln zur Not auch unter Win32s, wer sich das noch antut), die Algorithmen selbst sind aber lupenreines ANSI-C, die auch unter Linux und so kein Problem machen dürften. Das Giotto-Projekt ist für alle diejenigen gedacht, die selber genauer wissen wollen, was bei der Bildverarbeitung eigentlich geschieht und denen es nicht auf "Pretty Pictures" ankommt.

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.
 

Ein Hinweis: Die meisten unter uns sind keine Programmierer. Die Algorithmen der CCDLIB sind der Motor eines kompletten Public Domain Bildverarbeitungsprogramms GIOTTO, das hier fertig zum Download bereitsteht.

Algorithmen zur Bildverarbeitung

Alle Algorithmen des GIOTTO-Projektes sind in einer Routine gesammelt, die in reinem 32-Bit ANSI-C ohne jede Tricks und Seiteneffekte entwickelt worden ist und deshalb faktisch problemlos portabel sein dürfte. Der Quelltextfile heißt ccdlib.c, der dazugehörige Header ccdlib.h

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

Die CCDLIB_PictureparamStruct

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 );


Copyright und Disclaimer

Knowhow, Algorithmen und Quelltexte unterliegen einem Copyright.

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.
 

Wichtig: Ich arbeite nur während meiner ziemlich knappen Freizeit an diesem Projekt. Wenn es zwischen den einzelnen Entwicklungsschritten mal etwas länger dauert, so habt bitte Geduld mit mir. Das ist auch der Grund, warum ich nicht immer Fragen sofort beantworten kann.



Andere Websites zum Thema Video in der Astronomie

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