• Skip to content
  • Skip to link menu
KDE 3.5 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

kstars

fitsprocess.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           fitsprocess.h  -  Image processing utilities
00003                              -------------------
00004     begin                : Tue Feb 24 2004
00005     copyright            : (C) 2004 by Jasem Mutlaq
00006     email                : mutlaqja@ikarustech.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00017  
00018  #include <stdlib.h>
00019  #include <unistd.h>
00020  
00021  #include <kdebug.h>
00022  #include <klocale.h>
00023  #include <kprogress.h>
00024  #include <kapplication.h>
00025  
00026  #include <qimage.h>
00027  
00028  #include "fitsprocess.h"
00029  #include "fitsviewer.h"
00030  #include "fitsimage.h"
00031  
00032  #define ELEM_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; }
00033  
00034  FITSProcess::FITSProcess(FITSViewer *parent, QStringList darkFiles, QStringList flatFiles, QStringList darkflatFiles, int darkMode, int flatMode, int darkflatMode)
00035  {
00036    float * buffer      = NULL;
00037    darkCombineMode     = darkMode;
00038    flatCombineMode     = flatMode;
00039    darkflatCombineMode = darkflatMode;
00040    viewer              = parent;
00041    finalDark           = NULL;
00042    finalFlat           = NULL;
00043    finalDarkFlat       = NULL;
00044    npix                = viewer->image->width * viewer->image->height;
00045    
00046    darkFrames.setAutoDelete(true);
00047    flatFrames.setAutoDelete(true);
00048    darkflatFrames.setAutoDelete(true);
00049    
00050    KProgressDialog reduceProgress(0, 0, i18n("FITS Viewer"), i18n("Image Loading Process..."));
00051    reduceProgress.progressBar()->setTotalSteps(darkFiles.size() + flatFiles.size() + darkflatFiles.size());
00052    reduceProgress.setMinimumWidth(300);
00053    reduceProgress.show();
00054    
00055    int nprogress = 0;
00056    
00057    /* #1 Load dark frames */
00058    for (unsigned int i=0; i < darkFiles.size(); i++)
00059    {
00060      if ( (buffer = viewer->loadData(darkFiles[i].ascii(), buffer)) == NULL)
00061      {
00062         kdDebug() << "Error loading dark file " << darkFiles[i] << endl;
00063     break;
00064      }
00065      
00066      reduceProgress.progressBar()->setProgress(++nprogress);
00067      kapp->processEvents();
00068      darkFrames.append(buffer);
00069    }
00070    
00071    /* Load flat frames */
00072    for (unsigned int i=0; i < flatFiles.size(); i++)
00073    {
00074      if ( (buffer = viewer->loadData(flatFiles[i].ascii(), buffer)) == NULL)
00075      {
00076         kdDebug() << "Error loading flat file " << flatFiles[i] << endl;
00077     break;
00078      }
00079      
00080      reduceProgress.progressBar()->setProgress(++nprogress);
00081      kapp->processEvents();
00082      flatFrames.append(buffer);
00083    }
00084    
00085    /* Load dark frames for the flat field */
00086    for (unsigned int i=0; i < darkflatFiles.size(); i++)
00087    {
00088      if ( (buffer = viewer->loadData(darkflatFiles[i].ascii(), buffer)) == NULL)
00089      {
00090         kdDebug() << "Error loading dark flat file " << darkflatFiles[i] << endl;
00091     break;
00092      }
00093      
00094      reduceProgress.progressBar()->setProgress(++nprogress);
00095      kapp->processEvents();
00096      darkflatFrames.append(buffer);
00097    }
00098     
00099  }
00100  
00101 
00102  FITSProcess::~FITSProcess() {}
00103  
00104 float * FITSProcess::combine(QPtrList<float> & frames, int mode)
00105  {
00106     int nframes = frames.count();
00107     float *dest;
00108     float *narray;
00109     
00110     if (nframes == 0)
00111     {
00112       dest = NULL;
00113       return dest;
00114     }
00115     else if (nframes == 1)
00116     {
00117       dest = frames.at(0);
00118       return dest;
00119     }
00120     
00121     dest = frames.at(0);
00122     narray = (float *) malloc (nframes * sizeof(float));
00123     
00124     switch (mode)
00125     {
00126      /* Average */
00127      case 0:
00128       for (int i=0; i < npix; i++)
00129       {
00130         for (int j=0; j < nframes; j++)
00131       narray[j] = *((frames.at(j)) + i);
00132     dest[i] = average(narray, nframes);
00133 
00134       }
00135       break;
00136     /* Median */
00137      case 1:
00138       for (int i=0; i < npix; i++)
00139       {
00140         for (int j=0; j < nframes; j++)
00141       narray[j] = *((frames.at(j)) + i);
00142     dest[i] = quick_select(narray, nframes);
00143       }
00144       break;        
00145      }
00146      
00147      free(narray);
00148      return dest;
00149 }
00150  
00151  /*
00152  *  This Quickselect routine is based on the algorithm described in
00153  *  "Numerical recipies in C", Second Edition,
00154  *  Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5
00155  */
00156 float FITSProcess::quick_select(float * arr, int n) 
00157 {
00158     int low, high ;
00159     int median;
00160     int middle, ll, hh;
00161 
00162     low = 0 ; high = n-1 ; median = (low + high) / 2;
00163     for (;;) {
00164         if (high <= low) /* One element only */
00165             return arr[median] ;
00166 
00167         if (high == low + 1) {  /* Two elements only */
00168             if (arr[low] > arr[high])
00169                 ELEM_SWAP(arr[low], arr[high]) ;
00170             return arr[median] ;
00171         }
00172 
00173     /* Find median of low, middle and high items; swap into position low */
00174     middle = (low + high) / 2;
00175     if (arr[middle] > arr[high])    ELEM_SWAP(arr[middle], arr[high]) ;
00176     if (arr[low] > arr[high])       ELEM_SWAP(arr[low], arr[high]) ;
00177     if (arr[middle] > arr[low])     ELEM_SWAP(arr[middle], arr[low]) ;
00178 
00179     /* Swap low item (now in position middle) into position (low+1) */
00180     ELEM_SWAP(arr[middle], arr[low+1]) ;
00181 
00182     /* Nibble from each end towards middle, swapping items when stuck */
00183     ll = low + 1;
00184     hh = high;
00185     for (;;) {
00186         do ll++; while (arr[low] > arr[ll]) ;
00187         do hh--; while (arr[hh]  > arr[low]) ;
00188 
00189         if (hh < ll)
00190         break;
00191 
00192         ELEM_SWAP(arr[ll], arr[hh]) ;
00193     }
00194 
00195     /* Swap middle item (in position low) back into correct position */
00196     ELEM_SWAP(arr[low], arr[hh]) ;
00197 
00198     /* Re-set active partition */
00199     if (hh <= median)
00200         low = ll;
00201         if (hh >= median)
00202         high = hh - 1;
00203     }
00204 }
00205  
00206  float FITSProcess::average(float * array, int n)
00207  {
00208     double total=0;
00209     for (int i=0; i < n; i++)
00210       total += array[i];
00211       
00212     return (total / n);
00213  }
00214     
00215  
00216  void FITSProcess::subtract(float * img1, float * img2)
00217 {
00218    for (int i=0; i < npix; i++)
00219     if (img1[i] < img2[i])
00220       img1[i] = 0;
00221     else img1[i] -= img2[i];
00222      
00223 }
00224  
00225  void FITSProcess::divide(float * img1, float * img2)
00226 {
00227    for (int i=0; i < npix; i++)
00228    {
00229      if (img2[i] == 0)
00230        img1[i] = 0;
00231      else
00232        img1[i] = img1[i] / img2[i];
00233    }
00234    
00235 }
00236 
00237 void FITSProcess::normalize(float *buf)
00238 {
00239 
00240    float avg = average(buf, npix);
00241    if (!avg) return;
00242     
00243    if (avg < 0)
00244      avg += abs((int) min(buf));
00245     
00246   for (int i=0; i < npix; i++)
00247     buf[i] = buf[i] / avg;
00248 
00249 }
00250 
00251 float FITSProcess::min(float *buf)
00252 {
00253   float lmin= buf[0];
00254   
00255   for (int i=1; i < npix; i++)
00256     if (buf[i] < lmin) lmin = buf[i];
00257     
00258   return lmin;
00259 }
00260 
00261 void FITSProcess::reduce()
00262 {
00263    KProgressDialog reduceProgress(0, 0, i18n("FITS Viewer"), i18n("Image Reduction Process..."));
00264    reduceProgress.progressBar()->setTotalSteps(20);
00265    reduceProgress.setMinimumWidth(300);
00266    reduceProgress.show();
00267    
00268    reduceProgress.progressBar()->setProgress(1);
00269    kapp->processEvents();
00270    
00271    /* Combine darks */
00272    finalDark = combine(darkFrames, darkCombineMode);
00273    
00274    reduceProgress.progressBar()->setProgress(5);
00275    kapp->processEvents();
00276    
00277    /* Combine flats */
00278    finalFlat = combine(flatFrames, flatCombineMode);
00279    reduceProgress.progressBar()->setProgress(10);
00280    kapp->processEvents();
00281    
00282    /* Combine dark flats */
00283    finalDarkFlat = combine(darkflatFrames, darkflatCombineMode);
00284    reduceProgress.progressBar()->setProgress(12);
00285    kapp->processEvents();
00286      
00287    /* Subtract the dark frame */
00288    if (finalDark)
00289     subtract( viewer->imgBuffer, finalDark);
00290    reduceProgress.progressBar()->setProgress(14);
00291    kapp->processEvents();
00292    
00293 
00294    /* Subtract the fark frame from the flat field and then apply to the image buffer */
00295    if (finalFlat)
00296    {
00297      if (finalDarkFlat)
00298         subtract( finalFlat, finalDarkFlat);
00299       reduceProgress.progressBar()->setProgress(16);
00300       kapp->processEvents();
00301      
00302      normalize(finalFlat);
00303      reduceProgress.progressBar()->setProgress(18);
00304      kapp->processEvents();
00305      
00306      divide(viewer->imgBuffer, finalFlat);
00307    }
00308    
00309    reduceProgress.progressBar()->setProgress(20);
00310    kapp->processEvents();
00311 
00312 } 
00313  
00314 FITSProcessCommand::FITSProcessCommand(FITSViewer *parent)
00315 {
00316  
00317    viewer  = parent;
00318    oldImage  = new QImage();
00319    // TODO apply maximum compression against this buffer
00320    buffer = (float *) malloc (viewer->image->width * viewer->image->height * sizeof(float));
00321    memcpy(buffer, viewer->imgBuffer, viewer->image->width * viewer->image->height * sizeof(float));
00322  
00323  }
00324  
00325 FITSProcessCommand::~FITSProcessCommand()
00326 {
00327     free (buffer);
00328     delete (oldImage);
00329 }
00330  
00331 void FITSProcessCommand::execute()
00332 {
00333   memcpy(viewer->imgBuffer, buffer, viewer->image->width * viewer->image->height * sizeof(float));
00334   *oldImage = viewer->image->displayImage->copy();
00335 }
00336   
00337 void FITSProcessCommand::unexecute()
00338 {
00339   
00340   memcpy( viewer->imgBuffer, buffer, viewer->image->width * viewer->image->height * sizeof(float));
00341   viewer->calculateStats();
00342   *viewer->image->displayImage = oldImage->copy();
00343   viewer->image->zoomToCurrent();
00344  
00345 }
00346   
00347 QString FITSProcessCommand::name() const
00348 {
00349   return i18n("Image Reduction");
00350 }
00351 
00352 

kstars

Skip menu "kstars"
  • Main Page
  • Modules
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • keduca
  • kstars
Generated for API Reference by doxygen 1.5.9
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal