summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasem Mutlaq <mutlaqja@ikarustech.com>2016-11-06 15:59:06 (GMT)
committerJasem Mutlaq <mutlaqja@ikarustech.com>2016-11-06 15:59:06 (GMT)
commit7b5afc70b2fdd82640642d6ea40a6bd95a8f50ec (patch)
tree2c9253992bd1feca76c2d080a8424ba7448e71a3
parent9182ea136b1982120cd8680e333b57676db92039 (diff)
Adapting FITSData to work for KStars Lite and adding a static function to create an autostreched QImage from a FITS File
-rw-r--r--kstars/fitsviewer/fitsdata.cpp200
-rw-r--r--kstars/fitsviewer/fitsdata.h14
2 files changed, 199 insertions, 15 deletions
diff --git a/kstars/fitsviewer/fitsdata.cpp b/kstars/fitsviewer/fitsdata.cpp
index 1eb967e..97f24ac 100644
--- a/kstars/fitsviewer/fitsdata.cpp
+++ b/kstars/fitsviewer/fitsdata.cpp
@@ -34,13 +34,13 @@
#ifndef KSTARS_LITE
#include <KMessageBox>
-#endif
-#include <KLocalizedString>
-
#ifdef HAVE_WCSLIB
#include <wcshdr.h>
#include <wcsfix.h>
#endif
+#endif
+
+#include <KLocalizedString>
#include "ksutils.h"
#include "Options.h"
@@ -72,7 +72,6 @@ FITSData::FITSData(FITSMode fitsMode)
channels = 0;
wcs_coord = NULL;
fptr = NULL;
- histogram = NULL;
maxHFRStar = NULL;
tempFile = false;
starsSearched = false;
@@ -144,8 +143,10 @@ bool FITSData::loadFITS (const QString &inFilename, bool silent)
fits_report_error(stderr, status);
fits_get_errstatus(status, error_status);
errMessage = i18n("Could not open file %1. Error %2", filename, QString::fromUtf8(error_status));
+#ifndef KSTARS_LITE
if (silent == false)
KMessageBox::error(0, errMessage, i18n("FITS Open"));
+#endif
if (Options::fITSLogging())
qDebug() << errMessage;
return false;
@@ -156,8 +157,10 @@ bool FITSData::loadFITS (const QString &inFilename, bool silent)
fits_report_error(stderr, status);
fits_get_errstatus(status, error_status);
errMessage = i18n("FITS file open error (fits_get_img_param): %1", QString::fromUtf8(error_status));
+#ifndef KSTARS_LITE
if (silent == false)
KMessageBox::error(0, errMessage, i18n("FITS Open"));
+#endif
if (Options::fITSLogging())
qDebug() << errMessage;
return false;
@@ -166,8 +169,10 @@ bool FITSData::loadFITS (const QString &inFilename, bool silent)
if (stats.ndim < 2)
{
errMessage = i18n("1D FITS images are not supported in KStars.");
+#ifndef KSTARS_LITE
if (silent == false)
KMessageBox::error(0, errMessage, i18n("FITS Open"));
+#endif
if (Options::fITSLogging())
qDebug() << errMessage;
return false;
@@ -200,8 +205,10 @@ bool FITSData::loadFITS (const QString &inFilename, bool silent)
stats.bytesPerPixel = sizeof(double_t);
default:
errMessage = i18n("Bit depth %1 is not supported.", stats.bitpix);
+#ifndef KSTARS_LITE
if (silent == false)
KMessageBox::error(NULL, errMessage, i18n("FITS Open"));
+#endif
if (Options::fITSLogging())
qDebug() << errMessage;
return false;
@@ -214,8 +221,10 @@ bool FITSData::loadFITS (const QString &inFilename, bool silent)
if (naxes[0] == 0 || naxes[1] == 0)
{
errMessage = i18n("Image has invalid dimensions %1x%2", naxes[0], naxes[1]);
+#ifndef KSTARS_LITE
if (silent == false)
KMessageBox::error(0, errMessage, i18n("FITS Open"));
+#endif
if (Options::fITSLogging())
qDebug() << errMessage;
return false;
@@ -253,8 +262,10 @@ bool FITSData::loadFITS (const QString &inFilename, bool silent)
char errmsg[512];
fits_get_errstatus(status, errmsg);
errMessage = i18n("Error reading image: %1", QString(errmsg));
+#ifndef KSTARS_LITE
if (silent == false)
KMessageBox::error(NULL, errMessage, i18n("FITS Open"));
+#endif
fits_report_error(stderr, status);
if (Options::fITSLogging())
qDebug() << errMessage;
@@ -1027,7 +1038,7 @@ void FITSData::findCentroid(const QRectF &boundary, int initStdDev, int minEdgeW
}
template<typename T> void FITSData::findCentroid(const QRectF &boundary, int initStdDev, int minEdgeWidth)
-{
+{
double threshold=0,sum=0,avg=0,min=0;
int starDiameter=0;
int pixVal=0;
@@ -1036,8 +1047,10 @@ template<typename T> void FITSData::findCentroid(const QRectF &boundary, int ini
T *buffer = reinterpret_cast<T*>(imageBuffer);
double JMIndex = 100;
+ #ifndef KSTARS_LITE
if (histogram)
JMIndex = histogram->getJMIndex();
+ #endif
float dispersion_ratio=1.5;
@@ -1639,7 +1652,7 @@ template<typename T> void FITSData::applyFilter(FITSScale type, uint8_t *targetI
break;
case FITS_AUTO_STRETCH:
- {
+ {
/*double alpha = (pow(2, stats.bitpix) - 1) / (stats.max[0]-stats.min[0]);
double beta = (-1 * stats.min[0]) * alpha;
@@ -1706,6 +1719,7 @@ template<typename T> void FITSData::applyFilter(FITSScale type, uint8_t *targetI
case FITS_EQUALIZE:
{
+ #ifndef KSTARS_LITE
if (histogram == NULL)
return;
QVector<double> cumulativeFreq = histogram->getCumulativeFrequency();
@@ -1731,6 +1745,7 @@ template<typename T> void FITSData::applyFilter(FITSScale type, uint8_t *targetI
}
}
}
+ #endif
}
if (calcStats)
calculateStats(true);
@@ -1897,6 +1912,7 @@ void FITSData::getCenterSelection(int *x, int *y)
bool FITSData::checkWCS()
{
+#ifndef KSTARS_LITE
#ifdef HAVE_WCSLIB
int status=0;
@@ -1970,10 +1986,12 @@ bool FITSData::checkWCS()
HasWCS = true;
return HasWCS;
#endif
+#endif
return false;
}
+#ifndef KSTARS_LITE
#ifdef HAVE_WCSLIB
void FITSData::findObjectsInImage(struct wcsprm *wcs, double world[], double phi, double theta, double imgcrd[], double pixcrd[], int stat[])
{
@@ -2048,6 +2066,7 @@ void FITSData::findObjectsInImage(struct wcsprm *wcs, double world[], double phi
delete (num);
}
#endif
+#endif
QList<FITSSkyObject *> FITSData::getSkyObjects(){
return objList;
@@ -2686,7 +2705,9 @@ bool FITSData::checkDebayer()
if (stats.bitpix != 16 && stats.bitpix != 8)
{
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Only 8 and 16 bits bayered images supported."), i18n("Debayer error"));
+#endif
return false;
}
QString pattern(bayerPattern);
@@ -2699,7 +2720,7 @@ bool FITSData::checkDebayer()
else if (pattern == "GRBG")
debayerParams.filter = DC1394_COLOR_FILTER_GRBG;
else if (pattern == "BGGR")
- debayerParams.filter = DC1394_COLOR_FILTER_BGGR;
+ debayerParams.filter = DC1394_COLOR_FILTER_BGGR;
// We return unless we find a valid pattern
else
return false;
@@ -2740,20 +2761,22 @@ bool FITSData::debayer()
{
char errmsg[512];
fits_get_errstatus(status, errmsg);
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Error reading image: %1", QString(errmsg)));
+#endif
return false;
}
}
switch (data_type)
{
- case TBYTE:
- return debayer_8bit();
+ case TBYTE:
+ return debayer_8bit();
- case TUSHORT:
- return debayer_16bit();
+ case TUSHORT:
+ return debayer_16bit();
- default:
+ default:
return false;
}
@@ -2769,7 +2792,9 @@ bool FITSData::debayer_8bit()
if (destinationBuffer == NULL)
{
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Unable to allocate memory for temporary bayer buffer."), i18n("Debayer Error"));
+#endif
return false;
}
@@ -2791,7 +2816,9 @@ bool FITSData::debayer_8bit()
if ( error_code != DC1394_SUCCESS)
{
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Debayer failed (%1)", error_code), i18n("Debayer error"));
+#endif
channels=1;
delete[] destinationBuffer;
return false;
@@ -2805,7 +2832,9 @@ bool FITSData::debayer_8bit()
if (imageBuffer == NULL)
{
delete[] destinationBuffer;
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Unable to allocate memory for debayerd buffer."), i18n("Debayer Error"));
+#endif
return false;
}
}
@@ -2842,7 +2871,9 @@ bool FITSData::debayer_16bit()
if (destinationBuffer == NULL)
{
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Unable to allocate memory for temporary bayer buffer."), i18n("Debayer Error"));
+#endif
return false;
}
@@ -2864,7 +2895,9 @@ bool FITSData::debayer_16bit()
if ( error_code != DC1394_SUCCESS)
{
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Debayer failed (%1)", error_code), i18n("Debayer error"));
+#endif
channels=1;
delete[] destinationBuffer;
return false;
@@ -2878,7 +2911,9 @@ bool FITSData::debayer_16bit()
if (imageBuffer == NULL)
{
delete[] destinationBuffer;
+#ifndef KSTARS_LITE
KMessageBox::error(NULL, i18n("Unable to allocate memory for debayerd buffer."), i18n("Debayer Error"));
+#endif
return false;
}
}
@@ -3262,3 +3297,144 @@ QVector<int> FITSData::hysteresis(int width, int height, const QVector<int> &ima
#endif
+QImage FITSData::FITSToImage(const QString &filename)
+{
+ QImage fitsImage;
+ double min, max, val;
+
+ FITSData data;
+
+ bool rc = data.loadFITS(filename);
+ if (rc == false)
+ return fitsImage;
+
+ data.getMinMax(&min, &max);
+
+ if (min == max)
+ {
+ fitsImage.fill(Qt::white);
+ return fitsImage;
+ }
+
+ if (data.getNumOfChannels() == 1)
+ {
+ fitsImage = QImage(data.getWidth(), data.getHeight(), QImage::Format_Indexed8);
+
+ fitsImage.setColorCount(256);
+ for (int i=0; i < 256; i++)
+ fitsImage.setColor(i, qRgb(i,i,i));
+ }
+ else
+ {
+ fitsImage = QImage(data.getWidth(), data.getHeight(), QImage::Format_RGB32);
+ }
+
+ uint16_t w = data.getWidth();
+ uint16_t h = data.getHeight();
+ uint32_t size = data.getSize();
+
+ double dataMin = data.stats.mean[0] - data.stats.stddev[0];
+ double dataMax = data.stats.mean[0] + data.stats.stddev[0] * 3;
+
+ double bscale = 255. / (dataMax - dataMin);
+ double bzero = (-dataMin) * (255. / (dataMax - dataMin));
+
+ // Long way to do this since we do not want to use templated functions here
+ switch (data.getDataType())
+ {
+
+ case TBYTE:
+ {
+ uint8_t *buffer = data.getImageBuffer();
+ uint8_t bMin = dataMin < 0 ? 0 : dataMin;
+ uint8_t bMax = dataMax > 255 ? 255 : dataMax;
+ if (data.getNumOfChannels() == 1)
+ {
+ /* Fill in pixel values using indexed map, linear scale */
+ for (int j = 0; j < h; j++)
+ {
+ unsigned char *scanLine = fitsImage.scanLine(j);
+
+ for (int i = 0; i < w; i++)
+ {
+ val = qBound(bMin, buffer[j * w + i], bMax);
+ val = val * bscale + bzero;
+ scanLine[i]= qBound(0.0, val, 255.0);
+ }
+ }
+ }
+ else
+ {
+ double val=0,rval=0,gval=0,bval=0;
+ QRgb value;
+ /* Fill in pixel values using indexed map, linear scale */
+ for (int j = 0; j < h; j++)
+ {
+ QRgb *scanLine = reinterpret_cast<QRgb*>((fitsImage.scanLine(j)));
+
+ for (int i = 0; i < w; i++)
+ {
+ rval = qBound(bMin, buffer[j * w + i], bMax);
+ gval = qBound(bMin, buffer[j * w + i + size], bMax);
+ bval = qBound(bMin, buffer[j * w + i + size *2], bMax);;
+
+ value = qRgb(rval* bscale + bzero, gval* bscale + bzero, bval* bscale + bzero);
+
+ scanLine[i] = value;
+ }
+ }
+ }
+ }
+ break;
+
+
+ case TUSHORT:
+ {
+ uint16_t *buffer = reinterpret_cast<uint16_t*>(data.getImageBuffer());
+ uint16_t bMin = dataMin < 0 ? 0 : dataMin;
+ uint16_t bMax = dataMax > USHRT_MAX ? USHRT_MAX : dataMax;
+ if (data.getNumOfChannels() == 1)
+ {
+ /* Fill in pixel values using indexed map, linear scale */
+ for (int j = 0; j < h; j++)
+ {
+ unsigned char *scanLine = fitsImage.scanLine(j);
+
+ for (int i = 0; i < w; i++)
+ {
+ val = qBound(bMin, buffer[j * w + i], bMax);
+ val = val * bscale + bzero;
+ scanLine[i]= qBound(0.0, val, 255.0);
+ }
+ }
+ }
+ else
+ {
+ double rval=0,gval=0,bval=0;
+ QRgb value;
+ /* Fill in pixel values using indexed map, linear scale */
+ for (int j = 0; j < h; j++)
+ {
+ QRgb *scanLine = reinterpret_cast<QRgb*>((fitsImage.scanLine(j)));
+
+ for (int i = 0; i < w; i++)
+ {
+ rval = qBound(bMin, buffer[j * w + i], bMax);
+ gval = qBound(bMin, buffer[j * w + i + size], bMax);
+ bval = qBound(bMin, buffer[j * w + i + size *2], bMax);
+
+ value = qRgb(rval* bscale + bzero, gval* bscale + bzero, bval* bscale + bzero);
+
+ scanLine[i] = value;
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return fitsImage;
+}
diff --git a/kstars/fitsviewer/fitsdata.h b/kstars/fitsviewer/fitsdata.h
index 39ba120..4373aea 100644
--- a/kstars/fitsviewer/fitsdata.h
+++ b/kstars/fitsviewer/fitsdata.h
@@ -34,11 +34,12 @@
#include "skyobject.h"
+#ifndef KSTARS_LITE
#ifdef HAVE_WCSLIB
#include <wcs.h>
#endif
-#ifndef KSTARS_LITE
+
#include <kxmlguiwindow.h>
#endif
@@ -190,7 +191,9 @@ public:
// QVariant getFITSHeaderValue(QString &keyword);
// Histogram
+ #ifndef KSTARS_LITE
void setHistogram(FITSHistogram *inHistogram) { histogram = inHistogram; }
+ #endif
// Filter
void applyFilter(FITSScale type, uint8_t *image=NULL, float * min= NULL, float * max= NULL);
@@ -210,16 +213,19 @@ public:
int getFlipVCounter() const;
void setFlipVCounter(int value);
+ #ifndef KSTARS_LITE
#ifdef HAVE_WCSLIB
void findObjectsInImage(struct wcsprm *wcs, double world[], double phi, double theta, double imgcrd[], double pixcrd[], int stat[]);
#endif
+ #endif
QList<FITSSkyObject *> getSkyObjects();
QList<FITSSkyObject*> objList;//Does this need to be public??
+ // Create autostretch image from FITS File
+ static QImage FITSToImage(const QString &filename);
private:
-
void rotWCSFITS (int angle, int mirror);
bool checkCollision(Edge* s1, Edge*s2);
int calculateMinMax(bool refresh=false);
@@ -257,7 +263,9 @@ private:
QVector<int> hysteresis(int width, int height, const QVector<int> &image);
#endif
- FITSHistogram *histogram; // Pointer to the FITS data histogram
+ #ifndef KSTARS_LITE
+ FITSHistogram *histogram = NULL; // Pointer to the FITS data histogram
+ #endif
fitsfile* fptr; // Pointer to CFITSIO FITS file struct
int data_type; // FITS image data type (TBYTE, TUSHORT, TINT, TFLOAT, TLONGLONG, TDOUBLE)