Kstars

fitsdata.h
1/*
2 SPDX-FileCopyrightText: 2004 Jasem Mutlaq <mutlaqja@ikarustech.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5
6 Some code fragments were adapted from Peter Kirchgessner's FITS plugin
7 SPDX-FileCopyrightText: Peter Kirchgessner <http://members.aol.com/pkirchg>
8*/
9
10#pragma once
11
12#include "config-kstars.h"
13
14// From StellarSolver
15#ifdef HAVE_STELLARSOLVER
16#include <structuredefinitions.h>
17#else
18#include "structuredefinitions.h"
19#endif
20
21#include "kstarsdatetime.h"
22#include "bayer.h"
23#include "skybackground.h"
24#include "fitscommon.h"
25#include "fitsstardetector.h"
26#include "auxiliary/imagemask.h"
27
28#ifdef WIN32
29// This header must be included before fitsio.h to avoid compiler errors with Visual Studio
30#include <windows.h>
31#endif
32
33#include <fitsio.h>
34
35#include <QFuture>
36#include <QObject>
37#include <QRect>
38#include <QVariant>
39#include <QTemporaryFile>
40#include <QNetworkReply>
41#include <QTimer>
42
43#ifndef KSTARS_LITE
44#include <kxmlguiwindow.h>
45#ifdef HAVE_WCSLIB
46#include <wcs.h>
47#endif
48#endif
49
50#include "fitsskyobject.h"
51
52class QProgressDialog;
53
54class SkyPoint;
55class FITSHistogramData;
56class Edge;
57
58class FITSData : public QObject
59{
61
62 // Name of FITS file
63 Q_PROPERTY(QString filename READ filename)
64 // Extension
65 Q_PROPERTY(QString extension READ extension)
66 // Size of file in bytes
67 Q_PROPERTY(qint64 size READ size)
68 // Width in pixels
69 Q_PROPERTY(quint16 width READ width)
70 // Height in pixels
71 Q_PROPERTY(quint16 height READ height)
72 // FITS MODE --> Normal, Focus, Guide..etc
73 Q_PROPERTY(FITSMode mode MEMBER m_Mode)
74 // 1 channel (grayscale) or 3 channels (RGB)
75 Q_PROPERTY(quint8 channels READ channels)
76 // Bits per pixel
77 Q_PROPERTY(quint8 bpp READ bpp)
78 // Does FITS have WSC header?
79 Q_PROPERTY(bool hasWCS READ hasWCS)
80 // Does FITS have bayer data?
81 Q_PROPERTY(bool hasDebayer READ hasDebayer)
82
83 public:
84 explicit FITSData(FITSMode fitsMode = FITS_NORMAL);
85 explicit FITSData(const QSharedPointer<FITSData> &other);
86 ~FITSData() override;
87
88 /** Object to hold FITS Header records */
89 struct Record
90 {
91 Record() = default;
92 Record(QString k, QString v, QString c) : key(k), value(v), comment(c) {}
93 QString key; /** FITS Header Key */
94 QVariant value; /** FITS Header Value */
95 QString comment; /** FITS Header Comment, if any */
96 };
97
98 typedef enum
99 {
100 Idle,
101 Busy,
102 Success,
103 Failure
104 } WCSState;
105
106 ////////////////////////////////////////////////////////////////////////////////////////
107 ////////////////////////////////////////////////////////////////////////////////////////
108 /// Read and Write file/buffer Functions.
109 ////////////////////////////////////////////////////////////////////////////////////////
110 ////////////////////////////////////////////////////////////////////////////////////////
111 /**
112 * @brief loadFITS Loading FITS file asynchronously.
113 * @param inFilename Path to FITS file (or compressed fits.gz)
114 * @return A QFuture that can be watched until the async operation is complete.
115 */
116 QFuture<bool> loadFromFile(const QString &inFilename);
117
118 /**
119 * @brief loadFITSFromMemory Loading FITS from memory buffer.
120 * @param buffer The memory buffer containing the fits data.
121 * @return bool indicating success or failure.
122 */
123 bool loadFromBuffer(const QByteArray &buffer);
124
125 /**
126 * @brief parseSolution Parse the WCS solution information from the header into the given struct.
127 * @param solution Solution structure to fill out.
128 * @return True if parsing successful, false otherwise.
129 */
130 bool parseSolution(FITSImage::Solution &solution) const;
131
132 /* Save FITS or JPG/PNG*/
133 bool saveImage(const QString &newFilename);
134
135 // Access functions
136 void clearImageBuffers();
137 void setImageBuffer(uint8_t *buffer);
138 uint8_t const *getImageBuffer() const;
139 uint8_t *getWritableImageBuffer();
140
141 ////////////////////////////////////////////////////////////////////////////////////////
142 ////////////////////////////////////////////////////////////////////////////////////////
143 /// Statistics Functions.
144 ////////////////////////////////////////////////////////////////////////////////////////
145 ////////////////////////////////////////////////////////////////////////////////////////
146 // Calculate stats
147 void calculateStats(bool refresh = false, bool roi = false);
148 void saveStatistics(FITSImage::Statistic &other);
149 void restoreStatistics(FITSImage::Statistic &other);
150 FITSImage::Statistic const &getStatistics() const
151 {
152 return m_Statistics;
153 }
154
155 uint16_t width(bool roi = false) const
156 {
157 return roi ? m_ROIStatistics.width : m_Statistics.width;
158 }
159 uint16_t height(bool roi = false) const
160 {
161 return roi ? m_ROIStatistics.height : m_Statistics.height;
162 }
163 int64_t size(bool roi = false) const
164 {
165 return roi ? m_ROIStatistics.size : m_Statistics.size;
166 }
167 int channels() const
168 {
169 return m_Statistics.channels;
170 }
171 uint32_t samplesPerChannel(bool roi = false) const
172 {
173 return roi ? m_ROIStatistics.samples_per_channel : m_Statistics.samples_per_channel;
174 }
175 uint32_t dataType() const
176 {
177 return m_Statistics.dataType;
178 }
179 double getMin(uint8_t channel = 0, bool roi = false) const
180 {
181 return roi ? m_ROIStatistics.min[channel] : m_Statistics.min[channel];
182 }
183 double getMax(uint8_t channel = 0, bool roi = false) const
184 {
185 return roi ? m_ROIStatistics.max[channel] : m_Statistics.max[channel];
186
187 }
188 void setMinMax(double newMin, double newMax, uint8_t channel = 0);
189 void getMinMax(double *min, double *max, uint8_t channel = 0) const
190 {
191 *min = m_Statistics.min[channel];
192 *max = m_Statistics.max[channel];
193 }
194 void setStdDev(double value, uint8_t channel = 0)
195 {
196 m_Statistics.stddev[channel] = value;
197 }
198 double getStdDev(uint8_t channel = 0, bool roi = false ) const
199 {
200 return roi ? m_ROIStatistics.stddev[channel] : m_Statistics.stddev[channel];
201 }
202 double getAverageStdDev(bool roi = false) const;
203 void setMean(double value, uint8_t channel = 0)
204 {
205 m_Statistics.mean[channel] = value;
206 }
207 double getMean(uint8_t channel = 0, bool roi = false) const
208 {
209 return roi ? m_ROIStatistics.mean[channel] : m_Statistics.mean[channel];
210 }
211 // for single channel, just return the mean for channel zero
212 // for color, return the average
213 double getAverageMean(bool roi = false) const;
214 void setMedian(double val, uint8_t channel = 0)
215 {
216 m_Statistics.median[channel] = val;
217 }
218 // for single channel, just return the median for channel zero
219 // for color, return the average
220 double getAverageMedian(bool roi = false) const;
221 double getMedian(uint8_t channel = 0, bool roi = false) const
222 {
223 return roi ? m_ROIStatistics.median[channel] : m_Statistics.median[channel];
224 }
225
226 int getBytesPerPixel() const
227 {
228 return m_Statistics.bytesPerPixel;
229 }
230 void setSNR(double val)
231 {
232 m_Statistics.SNR = val;
233 }
234 double getSNR() const
235 {
236 return m_Statistics.SNR;
237 }
238 uint32_t bpp() const
239 {
240 switch(m_Statistics.dataType)
241 {
242 case TBYTE:
243 return 8;
244 case TSHORT:
245 case TUSHORT:
246 return 16;
247 case TLONG:
248 case TULONG:
249 case TFLOAT:
250 return 32;
251 case TLONGLONG:
252 case TDOUBLE:
253 return 64;
254 default:
255 return 8;
256 }
257 }
258 double getADU() const;
259
260 ////////////////////////////////////////////////////////////////////////////////////////
261 ////////////////////////////////////////////////////////////////////////////////////////
262 /// FITS Header Functions.
263 ////////////////////////////////////////////////////////////////////////////////////////
264 ////////////////////////////////////////////////////////////////////////////////////////
265 // FITS Record
266 bool getRecordValue(const QString &key, QVariant &value) const;
267 void updateRecordValue(const QString &key, QVariant value, const QString &comment);
268 const QList<Record> &getRecords() const
269 {
270 return m_HeaderRecords;
271 }
272
273 ////////////////////////////////////////////////////////////////////////////////////////
274 ////////////////////////////////////////////////////////////////////////////////////////
275 /// Star Search & HFR Functions.
276 ////////////////////////////////////////////////////////////////////////////////////////
277 ////////////////////////////////////////////////////////////////////////////////////////
278 // Star Detection - Native KStars implementation
279 void setStarAlgorithm(StarAlgorithm algorithm)
280 {
281 starAlgorithm = algorithm;
282 }
283 int getDetectedStars() const
284 {
285 return starCenters.count();
286 }
287 bool areStarsSearched() const
288 {
289 return starsSearched;
290 }
291 void appendStar(Edge *newCenter)
292 {
293 starCenters.append(newCenter);
294 }
295 const QList<Edge *> &getStarCenters() const
296 {
297 return starCenters;
298 }
299 QList<Edge *> getStarCentersInSubFrame(QRect subFrame) const;
300
301 void setStarCenters(const QList<Edge*> &centers)
302 {
303 qDeleteAll(starCenters);
304 starCenters = centers;
305 }
306 QFuture<bool> findStars(StarAlgorithm algorithm = ALGORITHM_CENTROID, const QRect &trackingBox = QRect());
307
308 void setSkyBackground(const SkyBackground &bg)
309 {
310 m_SkyBackground = bg;
311 }
312 const SkyBackground &getSkyBackground() const
313 {
314 return m_SkyBackground;
315 }
316 const QVariantMap &getSourceExtractorSettings() const
317 {
318 return m_SourceExtractorSettings;
319 }
320 void setSourceExtractorSettings(const QVariantMap &settings)
321 {
322 m_SourceExtractorSettings = settings;
323 }
324 // Use SEP (Sextractor Library) to find stars
325 template <typename T>
326 void getFloatBuffer(float *buffer, int x, int y, int w, int h) const;
327 //int findSEPStars(QList<Edge*> &, const int8_t &boundary = int8_t()) const;
328
329 // filter all stars that are visible through the given mask
330 int filterStars(QSharedPointer<ImageMask> mask);
331
332 // Half Flux Radius
333 const Edge &getSelectedHFRStar() const
334 {
335 return m_SelectedHFRStar;
336 }
337
338 // Calculates the median star eccentricity.
339 double getEccentricity();
340
341 double getHFR(HFRType type = HFR_AVERAGE);
342 double getHFR(int x, int y, double scale = 1.0);
343
344 ////////////////////////////////////////////////////////////////////////////////////////
345 ////////////////////////////////////////////////////////////////////////////////////////
346 /// Date & Time (WCS) Functions.
347 ////////////////////////////////////////////////////////////////////////////////////////
348 ////////////////////////////////////////////////////////////////////////////////////////
349
350 const KStarsDateTime &getDateTime() const
351 {
352 return m_DateTime;
353 }
354
355 // Set the time, for testing (doesn't set header field)
356 void setDateTime(const KStarsDateTime &t)
357 {
358 m_DateTime = t;
359 }
360
361 const QPoint getRoiCenter() const
362 {
363 return roiCenter;
364 }
365
366 void setRoiCenter(QPoint c)
367 {
368 roiCenter = c;
369 }
370
371 ////////////////////////////////////////////////////////////////////////////////////////
372 ////////////////////////////////////////////////////////////////////////////////////////
373 /// World Coordinate System (WCS) Functions.
374 ////////////////////////////////////////////////////////////////////////////////////////
375 ////////////////////////////////////////////////////////////////////////////////////////
376 // Check if a particular point exists within the image
377 bool contains(const QPointF &point) const;
378 // Does image have valid WCS?
379 bool hasWCS()
380 {
381 return HasWCS;
382 }
383 // Load WCS data
384 bool loadWCS();
385 // Get WCS State
386 WCSState getWCSState() const
387 {
388 return m_WCSState;
389 }
390
391 /**
392 * @brief wcsToPixel Given J2000 (RA0,DE0) coordinates. Find in the image the corresponding pixel coordinates.
393 * @param wcsCoord Coordinates of target
394 * @param wcsPixelPoint Return XY FITS coordinates
395 * @param wcsImagePoint Return XY Image coordinates
396 * @return True if conversion is successful, false otherwise.
397 */
398 bool wcsToPixel(const SkyPoint &wcsCoord, QPointF &wcsPixelPoint, QPointF &wcsImagePoint);
399
400 /**
401 * @brief pixelToWCS Convert Pixel coordinates to J2000 world coordinates
402 * @param wcsPixelPoint Pixel coordinates in XY Image space.
403 * @param wcsCoord Store back WCS world coordinate in wcsCoord
404 * @return True if successful, false otherwise.
405 */
406 bool pixelToWCS(const QPointF &wcsPixelPoint, SkyPoint &wcsCoord);
407
408 /**
409 * @brief injectWCS Add WCS keywords
410 * @param orientation Solver orientation, degrees E of N.
411 * @param ra J2000 Right Ascension
412 * @param dec J2000 Declination
413 * @param pixscale Pixel scale in arcsecs per pixel
414 * @param eastToTheRight if true, then when the image is rotated so that north is up, then east would be to the right on the image.
415 */
416 void injectWCS(double orientation, double ra, double dec, double pixscale, bool eastToTheRight);
417
418 ////////////////////////////////////////////////////////////////////////////////////////
419 ////////////////////////////////////////////////////////////////////////////////////////
420 /// Debayering Functions
421 ////////////////////////////////////////////////////////////////////////////////////////
422 ////////////////////////////////////////////////////////////////////////////////////////
423
424 // Debayer
425 bool hasDebayer()
426 {
427 return HasDebayer;
428 }
429
430 /**
431 * @brief debayer the 1-channel data to 3-channel RGB using the default debayer pattern detected in the FITS header.
432 * @param reload If true, it will read the image again from disk before performing debayering. This is necessary to attempt
433 * subsequent debayering processes on an already debayered image.
434 */
435 bool debayer(bool reload = false);
436 bool debayer_8bit();
437 bool debayer_16bit();
438 void getBayerParams(BayerParams *param);
439 void setBayerParams(BayerParams *param);
440
441 ////////////////////////////////////////////////////////////////////////////////////////
442 ////////////////////////////////////////////////////////////////////////////////////////
443 /// Public Histogram Functions
444 ////////////////////////////////////////////////////////////////////////////////////////
445 ////////////////////////////////////////////////////////////////////////////////////////
446
447 void resetHistogram()
448 {
449 m_HistogramConstructed = false;
450 }
451 double getHistogramBinWidth(int channel = 0)
452 {
453 return m_HistogramBinWidth[channel];
454 }
455
456 // Returns a vector with the counts (y-axis values) for the histogram.
457 const QVector<uint32_t> &getCumulativeFrequency(uint8_t channel = 0) const
458 {
459 return m_CumulativeFrequency[channel];
460 }
461 // Returns a vector with the values (x-axis values) for the histogram.
462 // The value returned is the low end of the histogram interval.
463 // The high end is this intensity plus the value returned by getHistogramBinWidth().
464 const QVector<double> &getHistogramIntensity(uint8_t channel = 0) const
465 {
466 return m_HistogramIntensity[channel];
467 }
468 const QVector<double> &getHistogramFrequency(uint8_t channel = 0) const
469 {
470 return m_HistogramFrequency[channel];
471 }
472 int getHistogramBinCount() const
473 {
474 return m_HistogramBinCount;
475 }
476
477 // Returns the histogram bin for the pixel at location x,y in the given channel.
478 int32_t histogramBin(int x, int y, int channel) const;
479
480 /**
481 * @brief getJMIndex Overall contrast of the image used in find centeroid algorithm. i.e. is the image diffuse?
482 * @return Value of JMIndex
483 */
484 double getJMIndex() const
485 {
486 return m_JMIndex;
487 }
488
489 bool isHistogramConstructed() const
490 {
491 return m_HistogramConstructed;
492 }
493 void constructHistogram();
494
495 ////////////////////////////////////////////////////////////////////////////////////////
496 ////////////////////////////////////////////////////////////////////////////////////////
497 /// Filters and Rotations Functions.
498 ////////////////////////////////////////////////////////////////////////////////////////
499 ////////////////////////////////////////////////////////////////////////////////////////
500 // Filter
501 void applyFilter(FITSScale type, uint8_t *image = nullptr, QVector<double> *targetMin = nullptr,
502 QVector<double> *targetMax = nullptr);
503
504 // Rotation counter. We keep count to rotate WCS keywords on save
505 int getRotCounter() const;
506 void setRotCounter(int value);
507
508 // Filename
509 const QString &filename() const
510 {
511 return m_Filename;
512 }
513 void setFilename(QString &filename)
514 {
515 m_Filename = filename;
516 }
517 const QString &compressedFilename() const
518 {
519 return m_compressedFilename;
520 }
521 bool isCompressed() const
522 {
523 return m_isCompressed;
524 }
525 // Extension
526 const QString &extension() const
527 {
528 return m_Extension;
529 }
530 void setExtension(const QString &extension)
531 {
532 m_Extension = extension;
533 }
534
535 // Horizontal flip counter. We keep count to rotate WCS keywords on save
536 int getFlipHCounter() const;
537 void setFlipHCounter(int value);
538
539 // Horizontal flip counter. We keep count to rotate WCS keywords on save
540 int getFlipVCounter() const;
541 void setFlipVCounter(int value);
542
543 ////////////////////////////////////////////////////////////////////////////////////////
544 ////////////////////////////////////////////////////////////////////////////////////////
545 /// Object Search Functions.
546 ////////////////////////////////////////////////////////////////////////////////////////
547 ////////////////////////////////////////////////////////////////////////////////////////
548#ifndef KSTARS_LITE
549#ifdef HAVE_WCSLIB
550 /**
551 * @brief search the current image for objects, either on the Skymap or a catalog
552 */
553 bool searchObjects();
554 /**
555 * @brief search the current image for catalog objects
556 */
557 bool searchCatObjects();
558 /**
559 * @brief get the search center point
560 * @return search center point
561 */
562 QPoint &catROIPt()
563 {
564 return m_CatROIPt;
565 }
566 /**
567 * @brief get the search circle radius
568 * @return search circle radius
569 */
570 int catROIRadius() const
571 {
572 return m_CatROIRadius;
573 }
574
575 bool findWCSBounds(double &minRA, double &maxRA, double &minDec, double &maxDec);
576#endif
577#endif
578 /**
579 * @brief set the search center circle with center point and radius
580 * @param circle center
581 * @param circle radius
582 */
583 void setCatSearchROI(const QPoint searchCenter, const int radius);
584 /**
585 * @brief get the sky map objects
586 * @return QList of objects
587 */
588 const QList<FITSSkyObject *> &getSkyObjects() const
589 {
590 return m_SkyObjects;
591 }
592 /**
593 * @brief get the catalog objects
594 * @return QList of catalog objects
595 */
596 const QList<CatObject> &getCatObjects() const
597 {
598 return m_CatObjects;
599 }
600 /**
601 * @brief get the catalog object filters
602 * @return QList of catalog object filters
603 */
604 const QStringList &getCatObjectsFilters() const
605 {
606 return m_CatObjectsFilters;
607 }
608 /**
609 * @brief set the catalog object filters
610 * @param QList of filters
611 */
612 void setCatObjectsFilters(const QStringList filters);
613 /**
614 * @brief get current status of catalog query
615 * @return whether catalog query in progress or not
616 */
617 const bool &getCatQueryInProgress() const
618 {
619 return m_CatQueryInProgress;
620 }
621 /**
622 * @brief highlight (and optionally lowlight) a particular catalog item
623 * @param highlight item
624 * @param lowlight item
625 */
626 bool highlightCatObject(const int hilite, const int lolite);
627 /**
628 * @brief applies current filters to object type list showing / hiding items as appropriate
629 */
630 void filterCatObjects();
631 /**
632 * @brief returns Object Type Label for the passed in Object Type Code
633 * @param object type code
634 * @return object type label
635 */
636 QString getCatObjectLabel(const QString code) const;
637
638 ////////////////////////////////////////////////////////////////////////////////////////
639 ////////////////////////////////////////////////////////////////////////////////////////
640 /// Image Conversion Functions.
641 ////////////////////////////////////////////////////////////////////////////////////////
642 ////////////////////////////////////////////////////////////////////////////////////////
643 // Create autostretch image from FITS File
644 static QImage FITSToImage(const QString &filename);
645
646 /**
647 * @brief ImageToFITS Convert an image file with supported format to a FITS file.
648 * @param filename full path to filename without extension
649 * @param format file extension. Supported formats are whatever supported by Qt (e.g. PNG, JPG,..etc)
650 * @param output Output temporary file path. The created file is generated by the function and store in output.
651 * @return True if conversion is successful, false otherwise.
652 */
653 static bool ImageToFITS(const QString &filename, const QString &format, QString &output);
654
655 QString getLastError() const;
656
657 static bool readableFilename(const QString &filename);
658
659 signals:
660 void converted(QImage);
661
662 /**
663 * @brief histogramReady Sends signal when histogram construction is complete.
664 */
665 void histogramReady();
666
667 /**
668 * @brief dataChanged Send signal when undelying raw data buffer data changed.
669 */
670 void dataChanged();
671
672 /**
673 * @brief headerChanged Send signal when undelying header data changed.
674 */
675 void headerChanged();
676
677 /**
678 * @brief loadingCatalogData Send signal when starting an external catalog data query
679 */
680 void loadingCatalogData();
681 /**
682 * @brief loadedCatalogData Send signal when finished an external catalog data query
683 */
684 void loadedCatalogData();
685 /**
686 * @brief catalogQueryFailed Send signal when an external catalog data query fails
687 * @param failure text
688 */
689 void catalogQueryFailed(const QString text);
690
691 public slots:
692 void makeRoiBuffer(QRect roi);
693
694 private:
695 void loadCommon(const QString &inFilename);
696 /**
697 * @brief privateLoad Load an image (FITS, RAW, or images supported by Qt like jpeg, png).
698 * @param Buffer pointer to image data. If buffer is emtpy, read from disk (m_Filename).
699 * @return true if successfully loaded, false otherwise.
700 */
701 bool privateLoad(const QByteArray &buffer);
702
703 // Load Qt-supported images.
704 bool loadCanonicalImage(const QByteArray &buffer);
705 // Load FITS images.
706 bool loadFITSImage(const QByteArray &buffer, const bool isCompressed = false);
707 // Load XISF images.
708 bool loadXISFImage(const QByteArray &buffer);
709 // Save XISF images.
710 bool saveXISFImage(const QString &newFilename);
711 // Load RAW images.
712 bool loadRAWImage(const QByteArray &buffer);
713
714 void rotWCSFITS(int angle, int mirror);
715 void calculateMinMax(bool refresh = false, bool roi = false);
716 void calculateMedian(bool refresh = false, bool roi = false);
717 bool checkDebayer();
718 void readWCSKeys();
719
720 /**
721 * @brief Update header info used by WCS based on solution info
722 * @param orientation Solver orientation, degrees E of N.
723 * @param ra J2000 Right Ascension
724 * @param dec J2000 Declination
725 * @param pixscale Pixel scale in arcsecs per pixel
726 * @param eastToTheRight if true, then when the image is rotated so that north is up, then east would be to the right on the image.
727 */
728 void updateWCSHeaderData(const double orientation, const double ra, const double dec, const double pixscale,
729 const bool eastToTheRight);
730
731 /**
732 * @brief Setup WCS parameters for non-FITS files so plate solved solutions can be used with catalog functionality.
733 */
734 void setupWCSParams();
735
736 // Record last FITS error
737 void recordLastError(int errorCode);
738 void logOOMError(uint32_t requiredMemory = 0);
739
740 // FITS Record
741 bool parseHeader();
742 //int getFITSRecord(QString &recordList, int &nkeys);
743
744 // Templated functions
745 template <typename T>
746 bool debayer();
747
748 template <typename T>
749 bool rotFITS(int rotate, int mirror);
750
751 // Apply Filter
752 template <typename T>
753 void applyFilter(FITSScale type, uint8_t *targetImage, QVector<double> * min = nullptr, QVector<double> * max = nullptr);
754
755 template <typename T>
756 void calculateMinMax(bool roi = false);
757 template <typename T>
758 void calculateMedian(bool roi = false);
759
760 template <typename T>
761 QPair<T, T> getParitionMinMax(uint32_t start, uint32_t stride, bool roi);
762
763 /* Calculate the Gaussian blur matrix and apply it to the image using the convolution filter */
764 QVector<double> createGaussianKernel(int size, double sigma);
765 template <typename T>
766 void convolutionFilter(const QVector<double> &kernel, int kernelSize);
767 template <typename T>
768 void gaussianBlur(int kernelSize, double sigma);
769
770 /* Calculate running average & standard deviation */
771 template <typename T>
772 void calculateStdDev( bool roi = false );
773
774 template <typename T>
775 void convertToQImage(double dataMin, double dataMax, double scale, double zero, QImage &image);
776
777 ////////////////////////////////////////////////////////////////////////////////////////
778 ////////////////////////////////////////////////////////////////////////////////////////
779 /// Private Histogram Functions.
780 ////////////////////////////////////////////////////////////////////////////////////////
781 ////////////////////////////////////////////////////////////////////////////////////////
782 template <typename T> void constructHistogramInternal();
783 template <typename T> int32_t histogramBinInternal(T value, int channel) const;
784 template <typename T> int32_t histogramBinInternal(int x, int y, int channel) const;
785
786 ////////////////////////////////////////////////////////////////////////////////////////
787 ////////////////////////////////////////////////////////////////////////////////////////
788 /// Private Catalog Functions.
789 ////////////////////////////////////////////////////////////////////////////////////////
790 ////////////////////////////////////////////////////////////////////////////////////////
791 /**
792 * @brief search the current image for Skymap objects
793 */
794 bool searchSkyMapObjects();
795 /**
796 * @brief search the current image for skymap objects
797 * @param startPoint the top left point on the sky map
798 * @param endPoint the bottom right point on the sky map
799 */
800 bool findObjectsInImage(SkyPoint startPoint, SkyPoint endPoint);
801 /**
802 * @brief search Simbad for catalog objects in the current image
803 * @param searchCenter is the center point for the search
804 * @param search circle radius
805 */
806 bool findSimbadObjectsInImage(SkyPoint searchCenter, double radius);
807 /**
808 * @brief whether the Object Type passed in should be displayed
809 * @param object type
810 * @return whether the passed in object type should be displayed
811 */
812 bool getCatObjectFilter(const QString type) const;
813 /**
814 * @brief called when a Simbad query response has arrived
815 * @param reply
816 */
817 void simbadResponseReady(QNetworkReply *reply);
818 /**
819 * @brief called when a Simbad query times out
820 */
821 void catTimeout();
822 /**
823 * @brief add catalog object to the array of objects
824 * @param name of object
825 * @param type of object
826 * @param coord of object
827 * @param dist of object from search point
828 * @param magnitude of object (if available)
829 * @param size of object (if available)
830 * @return whether the add was successful
831 */
832 bool addCatObject(const int num, const QString name, const QString type, const QString coord, const double dist,
833 const double magnitude, const QString sizeStr);
834
835 /// Pointer to CFITSIO FITS file struct
836 fitsfile *fptr { nullptr };
837 /// Generic data image buffer
838 uint8_t *m_ImageBuffer { nullptr };
839 /// Above buffer size in bytes
840 uint32_t m_ImageBufferSize { 0 };
841 /// Image Buffer if Selection is to be done
842 uint8_t *m_ImageRoiBuffer { nullptr };
843 /// Above buffer size in bytes
844 uint32_t m_ImageRoiBufferSize { 0 };
845 /// Is this a temporary file or one loaded from disk?
846 bool m_isTemporary { false };
847 /// is this file compress (.fits.fz)?
848 bool m_isCompressed { false };
849 /// Did we search for stars yet?
850 bool starsSearched { false };
851 ///Star Selection Algorithm
852 StarAlgorithm starAlgorithm { ALGORITHM_GRADIENT };
853 /// Do we have WCS keywords in this FITS data?
854 bool HasWCS { false }; /// Do we have WCS keywords in this FITS data?
855 /// Is the image debayarable?
856 bool HasDebayer { false };
857 /// Buffer to hold fpack uncompressed data
858 uint8_t *m_PackBuffer {nullptr};
859
860 /// Our very own file name
861 QString m_Filename, m_compressedFilename, m_Extension;
862 /// FITS Mode (Normal, WCS, Guide, Focus..etc)
863 FITSMode m_Mode;
864 // FITS Observed UTC date time
865 KStarsDateTime m_DateTime;
866
867 /// How many times the image was rotated? Useful for WCS keywords rotation on save.
868 int rotCounter { 0 };
869 /// How many times the image was flipped horizontally?
870 int flipHCounter { 0 };
871 /// How many times the image was flipped vertically?
872 int flipVCounter { 0 };
873
874 /// WCS Struct
875 struct wcsprm *m_WCSHandle
876 {
877 nullptr
878 };
879 /// Number of coordinate representations found.
880 int m_nwcs {0};
881 WCSState m_WCSState { Idle };
882 /// All the stars we detected, if any.
883 QList<Edge *> starCenters;
884 QList<Edge *> localStarCenters;
885 /// The biggest fattest star in the image.
886 Edge m_SelectedHFRStar;
887
888 /// Bayer parameters
889 BayerParams debayerParams;
890 QTemporaryFile m_TemporaryDataFile;
891
892 /// Data type of fits pixel in the image. Used when saving FITS again.
893 /// There is bit depth and also data type. They're not the same.
894 /// 16bit can be either SHORT_IMG or USHORT_IMG, so m_FITSBITPIX specifies which is
895 int m_FITSBITPIX {USHORT_IMG};
896 FITSImage::Statistic m_Statistics;
897 FITSImage::Statistic m_ROIStatistics;
898
899 // A list of header records
900 QList<Record> m_HeaderRecords;
901
902 QList<FITSSkyObject *> m_SkyObjects;
903 QList<CatObject> m_CatObjects;
904 QStringList m_CatObjectsFilters;
905 QString m_CatObjQuery;
906 bool m_ObjectsSearched {false};
907 bool m_CatObjectsSearched {false};
908 void resetCatObjectsSearched()
909 {
910 m_CatObjectsSearched = false;
911 }
912
913 FITSImage::Solution m_PlateSolveSolution { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, FITSImage::POSITIVE, 0.0, 0.0 };
914
915 QString m_LastError;
916
917 ////////////////////////////////////////////////////////////////////////////////////////
918 ////////////////////////////////////////////////////////////////////////////////////////
919 /// Histogram Variables
920 ////////////////////////////////////////////////////////////////////////////////////////
921 ////////////////////////////////////////////////////////////////////////////////////////
922 QVector<QVector<uint32_t>> m_CumulativeFrequency;
923 QVector<QVector<double>> m_HistogramIntensity;
924 QVector<QVector<double>> m_HistogramFrequency;
925 QVector<double> m_HistogramBinWidth;
926 uint16_t m_HistogramBinCount { 0 };
927 double m_JMIndex { 1 };
928 bool m_HistogramConstructed { false };
929
930 ////////////////////////////////////////////////////////////////////////////////////////
931 ////////////////////////////////////////////////////////////////////////////////////////
932 /// Star Detector
933 ////////////////////////////////////////////////////////////////////////////////////////
934 ////////////////////////////////////////////////////////////////////////////////////////
935 // Sky Background
936 SkyBackground m_SkyBackground;
937 // Detector Settings
938 QVariantMap m_SourceExtractorSettings;
939 QFuture<bool> m_StarFindFuture;
941
942 // Cached values for hfr and eccentricity computations
943 double cacheHFR { -1 };
944 HFRType cacheHFRType { HFR_AVERAGE };
945 double cacheEccentricity { -1 };
946 QPoint roiCenter;
947
948 // Catalog Objects
949 QSharedPointer<QNetworkAccessManager> m_NetworkAccessManager;
950 QTimer m_CatQueryTimer;
951 bool m_CatQueryInProgress { false };
952 bool m_CatUpdateTable { false };
953 QPoint m_CatROIPt { -1, -1 };
954 int m_CatROIRadius { -1 };
955};
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
The sky coordinates of a point in the sky.
Definition skypoint.h:45
void append(QList< T > &&value)
qsizetype count() const const
Q_OBJECTQ_OBJECT
Q_PROPERTY(...)
Object to hold FITS Header records.
Definition fitsdata.h:90
QString comment
FITS Header Value.
Definition fitsdata.h:95
QVariant value
FITS Header Key.
Definition fitsdata.h:94
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:11:15 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.