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

kstars

fitshistogram.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           fitshistogram.cpp  -  FITS Historgram
00003                           -----------------
00004     begin                : Thu Mar 4th 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 "fitshistogram.h"
00019  #include "fitsviewer.h"
00020  #include "fitsimage.h"
00021  #include "indi/fitsrw.h"
00022  
00023  #include <math.h>
00024  #include <stdlib.h>
00025  
00026  #include <qpainter.h>
00027  #include <qslider.h>
00028  #include <qcursor.h>
00029  #include <qpen.h>
00030  #include <qpixmap.h>
00031  #include <qradiobutton.h>
00032  #include <qpushbutton.h>
00033  
00034  #include <kdebug.h>
00035  #include <klineedit.h>
00036  #include <klocale.h>
00037  
00038  
00039  
00040  FITSHistogram::FITSHistogram(QWidget *parent, const char * name) : histDialog(parent, name)
00041  {
00042    viewer = (FITSViewer *) parent;
00043    
00044    setModal(false);
00045    
00046    minSlider->setMinValue(0);
00047    minSlider->setMaxValue(BARS-1);
00048    minSlider->setValue(0);
00049    
00050    maxSlider->setMinValue(0);
00051    maxSlider->setMaxValue(BARS-1);
00052    maxSlider->setValue(BARS-1);
00053    
00054    type = 0;
00055    napply=0;
00056    
00057    histFrame->setCursor(Qt::CrossCursor);
00058    histFrame->setMouseTracking(true);
00059    setMouseTracking(true);
00060    
00061    connect(minSlider, SIGNAL(valueChanged(int)), this, SLOT(updateBoxes()));
00062    connect(minSlider, SIGNAL(valueChanged(int)), this, SLOT(updateIntenFreq(int )));
00063    connect(maxSlider, SIGNAL(valueChanged(int)), this, SLOT(updateBoxes()));
00064    connect(maxSlider, SIGNAL(valueChanged(int)), this, SLOT(updateIntenFreq(int )));
00065    connect(applyB, SIGNAL(clicked()), this, SLOT(applyScale()));
00066 
00067    constructHistogram(viewer->imgBuffer);
00068    
00069    updateBoxes();
00070    
00071 }
00072  
00073  FITSHistogram::~FITSHistogram() {}
00074  
00075 void FITSHistogram::updateBoxes()
00076 {
00077         if (minSlider->value() == BARS)
00078      minOUT->setText(QString("%1").arg((int) viewer->stats.max));
00079     else
00080      minOUT->setText(QString("%1").arg( (int) ( ceil (minSlider->value() * binSize) + viewer->stats.min)));
00081      
00082     if (maxSlider->value() == BARS)
00083      maxOUT->setText(QString("%1").arg((int) viewer->stats.max));
00084     else
00085      maxOUT->setText(QString("%1").arg( (int) ( ceil (maxSlider->value() * binSize) + viewer->stats.min)));
00086 
00087         update();
00088 }
00089 
00090 void FITSHistogram::applyScale()
00091 {
00092   int swap;
00093   int min = minSlider->value();
00094   int max = maxSlider->value();
00095   
00096   FITSHistogramCommand *histC;
00097   //kdDebug() << "Width " << viewer->image->width << endl;
00098   
00099   if (min > max)
00100   {
00101     swap = min;
00102     min  = max;
00103     max  = swap;
00104   }
00105   
00106    min  = (int) (min * binSize + viewer->stats.min);
00107    max  = (int) (max * binSize + viewer->stats.min);
00108 
00109   
00110   napply++;
00111   
00112   // Auto
00113   if (autoR->isOn())
00114     type = 0;
00115   // Linear
00116   else if (linearR->isOn())
00117     type = 1;
00118   // Log
00119   else if (logR->isOn())
00120     type = 2;
00121   // Exp
00122   else if (sqrtR->isOn())
00123     type = 3;
00124   
00125   histC = new FITSHistogramCommand(viewer, this, type, min, max);
00126   viewer->history->addCommand(histC);
00127     
00128 }
00129  
00130 void FITSHistogram::constructHistogram(float * buffer)
00131 {
00132   int maxHeight = 0;
00133   int height    = histFrame->height(); 
00134   int id;
00135   int index;
00136   int range = (int) (viewer->stats.max - viewer->stats.min);
00137     
00138   for (int i=0; i < BARS; i++)
00139       histArray[i] = 0;
00140     binSize = ( (double) range / (double) BARS); 
00141     
00142     //kdDebug() << "#2" << endl; 
00143     if (binSize == 0 || buffer == NULL)
00144      return;
00145     
00146      for (int i=0; i < viewer->stats.width * viewer->stats.height; i++)
00147      {
00148         id = (int) ((buffer[i] - viewer->stats.min) / binSize);
00149         if (id >= BARS) id = BARS - 1;
00150         histArray[id]++;
00151     
00152      }
00153      
00154      if (binSize < 1)
00155      for (int i=0; i < BARS - 1; i++)
00156          if (histArray[i] == 0)
00157      {
00158         index = (int) ceil(i * binSize);
00159             if (index == (int) (ceil ((i+1) * binSize)))
00160                 histArray[i] = histArray[i+1];
00161          }
00162   
00163  maxHeight = findMax() / height;
00164  
00165  kdDebug() << "Maximum height is " << maxHeight << " -- binsize " << binSize << endl;
00166  
00167  histogram = new QPixmap(500, 150, 1);
00168  histogram->fill(Qt::black);
00169  QPainter p(histogram);
00170  QPen pen( white, 1);
00171  p.setPen(pen);
00172    
00173  for (int i=0; i < BARS; i++)
00174      p.drawLine(i, height , i, height - (int) ((double) histArray[i] / (double) maxHeight)); 
00175   
00176 }
00177 
00178 void FITSHistogram::paintEvent( QPaintEvent */*e*/)
00179 {
00180   int height    = histFrame->height(); 
00181   int xMin = minSlider->value(), xMax = maxSlider->value();
00182   
00183   QPainter p(histFrame);
00184   QPen pen;
00185   pen.setWidth(1);
00186   
00187   bitBlt(histFrame, 0, 0, histogram);
00188   
00189   pen.setColor(blue);
00190   p.setPen(pen);
00191   
00192   p.drawLine(xMin, height - 2, xMin, height/2 -2);
00193   pen.setColor(red);
00194   p.setPen(pen);
00195   p.drawLine(xMax, 2, xMax, height/2 -2);
00196   
00197   
00198 }
00199 
00200 void FITSHistogram::mouseMoveEvent( QMouseEvent *e)
00201 {
00202   int x = e->x();
00203   int y = e->y();
00204   
00205   x -= histFrame->x();
00206   y -= histFrame->y();
00207   
00208   if (x < 0 || x >= BARS || y < 0 || y > histFrame->height() )
00209    return;
00210   
00211   updateIntenFreq(x);
00212   
00213 }
00214 
00215 void FITSHistogram::updateIntenFreq(int x)
00216 {
00217 
00218   int index = (int) ceil(x * binSize);
00219     
00220   intensityOUT->setText(QString("%1").arg((int) ( index + viewer->stats.min)));
00221   
00222   frequencyOUT->setText(QString("%1").arg(histArray[x]));
00223   
00224 }
00225 
00226 
00227 int FITSHistogram::findMax()
00228 {
00229   int max =0;
00230   
00231   for (int i=0; i < BARS; i++)
00232     if (histArray[i] > max) max = histArray[i];
00233     
00234   return max;
00235 }
00236 
00237 FITSHistogramCommand::FITSHistogramCommand(QWidget * parent, FITSHistogram *inHisto, int newType, int lmin, int lmax)
00238 {
00239   viewer    = (FITSViewer *) parent;
00240   type      = newType;
00241   histo     = inHisto;
00242   oldImage  = new QImage();
00243   // TODO apply maximum compression against this buffer
00244   buffer = (float *) malloc (viewer->image->width * viewer->image->height * sizeof(float));
00245    
00246   //if (buffer == NULL)
00247    //return;
00248    min = lmin;
00249    max = lmax;
00250 }
00251 
00252 FITSHistogramCommand::~FITSHistogramCommand() 
00253 {
00254   free(buffer);
00255   delete (oldImage);
00256 }
00257             
00258 void FITSHistogramCommand::execute()
00259 {
00260   float val, bufferVal;
00261   double coeff;
00262   FITSImage *image = viewer->image;
00263   int width  = image->width;
00264   int height = image->height;
00265   
00266   memcpy(buffer, viewer->imgBuffer,image->width * image->height * sizeof(float));
00267   *oldImage = image->displayImage->copy();
00268  
00269   switch (type)
00270   {
00271     case FITSImage::FITSAuto:
00272     case FITSImage::FITSLinear:
00273     for (int i=0; i < height; i++)
00274       for (int j=0; j < width; j++)
00275       {
00276               bufferVal = viewer->imgBuffer[i * width + j];
00277           if (bufferVal < min) bufferVal = min;
00278           else if (bufferVal > max) bufferVal = max;
00279           //val = (int) (255. * ((double) (bufferVal - min) / (double) (max - min)));
00280           //val = (int) (max * ((double) (bufferVal - min) / (double) (max - min)));
00281           //val = (int) (bufferVal - min) * (max - min) + min;
00282           //if (val < min) val = min;
00283           //else if (val > max) val = max;
00284           //image->reducedImgBuffer[i * width + j] = val;
00285           viewer->imgBuffer[i * width + j] = bufferVal;
00286               
00287       }
00288      break;
00289      
00290     case FITSImage::FITSLog:
00291     //coeff = 255. / log(1 + max);
00292     coeff = max / log(1 + max);
00293     
00294     for (int i=0; i < height; i++)
00295       for (int j=0; j < width; j++)
00296       {
00297               bufferVal = viewer->imgBuffer[i * width + j];
00298           if (bufferVal < min) bufferVal = min;
00299           else if (bufferVal > max) bufferVal = max;
00300           val = (coeff * log(1 + bufferVal));
00301           if (val < min) val = min;
00302           else if (val > max) val = max;
00303           viewer->imgBuffer[i * width + j] = val;
00304           //image->reducedImgBuffer[i * width + j] = val;
00305               //displayImage->setPixel(j, height - i - 1, val);
00306       }
00307       break;
00308       
00309     case FITSImage::FITSSqrt:
00310     //coeff = 255. / sqrt(max);
00311     coeff = max / sqrt(max);
00312     
00313     for (int i=0; i < height; i++)
00314       for (int j=0; j < width; j++)
00315       {
00316               bufferVal = (int) viewer->imgBuffer[i * width + j];
00317           if (bufferVal < min) bufferVal = min;
00318           else if (bufferVal > max) bufferVal = max;
00319           val = (int) (coeff * sqrt(bufferVal));
00320           //image->reducedImgBuffer[i * width + j] = val;
00321           viewer->imgBuffer[i * width + j] = val;
00322               //displayImage->setPixel(j, height - i - 1, val);
00323       }
00324       
00325       break;
00326     
00327      
00328     default:
00329      break;
00330   }
00331        
00332    //int lmin= image->reducedImgBuffer[0];
00333    float lmin= viewer->imgBuffer[0];
00334    float lmax= viewer->imgBuffer[0];
00335    int totalPix = width * height;
00336    
00337    for (int i=1; i < totalPix; i++)
00338     //if ( image->reducedImgBuffer[i] < lmin) lmin = image->reducedImgBuffer[i];
00339     if ( viewer->imgBuffer[i] < lmin) lmin = viewer->imgBuffer[i];
00340     else if (viewer->imgBuffer[i] > lmax) lmax = viewer->imgBuffer[i];
00341     
00342    double datadiff = 255.;
00343    double pixdiff = lmax - lmin;
00344    double offs = -lmin * datadiff / pixdiff;
00345    double scale = datadiff / pixdiff;
00346    int tdata = 0;
00347   
00348      
00349  for (int i=0; i < height; i++)
00350   for (int j=0; j < width; j++)
00351   {
00352            //bp8 = (FITS_BITPIX8) image->reducedImgBuffer[i * width + j];
00353        //bp8 = (FITS_BITPIX8) 
00354            tdata = (long) (viewer->imgBuffer[i * width + j] * scale + offs);
00355            if (tdata < 0) tdata = 0;
00356            else if (tdata > 255) tdata = 255;
00357        image->displayImage->setPixel(j, height - i - 1, tdata);
00358   }
00359   
00360   viewer->calculateStats();
00361   
00362   //viewer->updateImgBuffer();
00363   if (histo != NULL)
00364   {
00365     histo->constructHistogram(viewer->imgBuffer);
00366     histo->update();
00367     histo->updateBoxes();
00368   }
00369   
00370   viewer->image->zoomToCurrent();
00371   viewer->fitsChange();
00372   
00373 }
00374 
00375 void FITSHistogramCommand::unexecute()
00376 {
00377   memcpy( viewer->imgBuffer, buffer, viewer->image->width * viewer->image->height * sizeof(float));
00378   viewer->calculateStats();
00379   *viewer->image->displayImage = oldImage->copy();
00380   viewer->image->zoomToCurrent();
00381   
00382   if (histo != NULL)
00383   {
00384     histo->constructHistogram(viewer->imgBuffer);
00385     histo->update();
00386     histo->updateBoxes();
00387   }
00388 }
00389 
00390 QString FITSHistogramCommand::name() const
00391 {
00392 
00393  switch (type)
00394  {
00395   case 0:
00396     return i18n("Auto Scale");
00397     break;
00398   case 1:
00399     return i18n("Linear Scale");
00400     break;
00401   case 2:
00402     return i18n("Logarithmic Scale");
00403     break;  
00404   case 3:
00405     return i18n("Square Root Scale");
00406     break;
00407   default:
00408    break;
00409  }
00410  
00411  return i18n("Unknown");
00412 
00413 }
00414 
00415 
00416 
00417  
00418 
00419 #include "fitshistogram.moc"

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