File indexing completed on 2024-04-28 15:09:09
0001 /* 0002 SPDX-FileCopyrightText: 2021 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <set> 0010 #include <QJsonObject> 0011 #include <QJsonArray> 0012 0013 #include "fitsviewer/fitsdata.h" 0014 0015 class BadPixel 0016 { 0017 public: 0018 BadPixel() {}; 0019 explicit BadPixel(uint16_t _x, uint16_t _y, double _value) : x(_x), y(_y), value(_value) {} 0020 bool operator<(const BadPixel &rhs) const 0021 { 0022 return value < rhs.value; 0023 } 0024 QJsonObject json() const; 0025 uint16_t x{0}, y{0}; 0026 double value {0}; 0027 }; 0028 0029 typedef std::multiset<BadPixel> BadPixelSet; 0030 0031 class DefectMap : public QObject 0032 { 0033 Q_OBJECT 0034 0035 // Hot Pixels Aggressiveness 0036 Q_PROPERTY(int HotPixelAggressiveness MEMBER m_HotPixelsAggressiveness) 0037 // Cold Pixels Aggressiveness 0038 Q_PROPERTY(int ColdPixelAggressiveness MEMBER m_ColdPixelsAggressiveness) 0039 // Hot Pixels Enabled 0040 Q_PROPERTY(bool HotEnabled READ hotEnabled WRITE setHotEnabled) 0041 // Cold Pixels Enabled 0042 Q_PROPERTY(bool ColdEnabled READ coldEnabled WRITE setColdEnabled) 0043 0044 public: 0045 DefectMap(); 0046 0047 void setHotEnabled(bool enabled); 0048 void setColdEnabled(bool enabled); 0049 void setDarkData(const QSharedPointer<FITSData> &data); 0050 bool load(const QString &filename); 0051 bool save(const QString &filename, const QString &camera); 0052 void initBadPixels(); 0053 0054 const BadPixelSet &hotPixels() const 0055 { 0056 return m_HotPixels; 0057 } 0058 const BadPixelSet &coldPixels() const 0059 { 0060 return m_ColdPixels; 0061 } 0062 0063 bool hotEnabled() const 0064 { 0065 return m_HotEnabled; 0066 } 0067 bool coldEnabled() const 0068 { 0069 return m_ColdEnabled; 0070 } 0071 const QString &filename() const 0072 { 0073 return m_Filename; 0074 } 0075 0076 const BadPixelSet::const_iterator hotThreshold() const 0077 { 0078 return (m_HotEnabled ? m_HotPixelsThreshold : m_HotPixels.end()); 0079 } 0080 const BadPixelSet::const_iterator coldThreshold() const 0081 { 0082 return (m_ColdEnabled ? m_ColdPixelsThreshold : m_ColdPixels.begin()); 0083 } 0084 uint32_t hotCount() const 0085 { 0086 return m_HotPixelsCount; 0087 } 0088 uint32_t coldCount() const 0089 { 0090 return m_ColdPixelsCount; 0091 } 0092 0093 void filterPixels(); 0094 signals: 0095 // void hotPixelsUpdated(const BadPixelSet::const_iterator &start, const BadPixelSet::const_iterator &end); 0096 // void coldPixelsUpdated(const BadPixelSet::const_iterator &start, const BadPixelSet::const_iterator &end); 0097 void pixelsUpdated(uint32_t hotPixelsCount, uint32_t coldPixelsCount); 0098 0099 private: 0100 double getHotThreshold(uint8_t aggressiveness); 0101 double getColdThreshold(uint8_t aggressiveness); 0102 double calculateSigma(uint8_t aggressiveness); 0103 template <typename T> 0104 void initBadPixelsInternal(double hotPixelThreshold, double coldPixelThreshold); 0105 0106 BadPixelSet m_ColdPixels, m_HotPixels; 0107 BadPixelSet::const_iterator m_ColdPixelsThreshold, m_HotPixelsThreshold; 0108 uint8_t m_HotPixelsAggressiveness {75}, m_ColdPixelsAggressiveness {75}; 0109 uint32_t m_HotPixelsCount {0}, m_ColdPixelsCount {0}; 0110 double m_HotSigma {0}, m_ColdSigma {0}; 0111 double m_Median {0}, m_StandardDeviation {0}; 0112 bool m_HotEnabled {true}, m_ColdEnabled {true}; 0113 QString m_Filename, m_Camera; 0114 0115 QSharedPointer<FITSData> m_DarkData; 0116 0117 }; 0118