File indexing completed on 2024-04-28 15:09:09

0001 /*
0002     SPDX-FileCopyrightText: 2016 Jasem Mutlaq <mutlaqja@ikarustech.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "indi/indicamera.h"
0010 #include "indi/indidustcap.h"
0011 #include "darkview.h"
0012 #include "defectmap.h"
0013 #include "ekos/ekos.h"
0014 
0015 #include <QFutureWatcher>
0016 
0017 class TestDefects;
0018 class TestSubtraction;
0019 
0020 namespace Ekos
0021 {
0022 
0023 /**
0024  * @brief The DarkProcessor class
0025  *
0026  * Denoises a light image by either subtracting a dark frame or applying a defect map.
0027  *
0028  * The primary denoise function searches first for defect maps that matches the criteria of the passed parameters.
0029  * These include sensor binning, size, temperature, and date. If a defect map is found, then it is loaded from disk and all the bad
0030  * pixels are treated with a 3x3 median filter. If no defect map is found, it searches for suitable dark frames and if any is found then
0031  * a simple subtraction is applied.
0032  *
0033  * @author Jasem Mutlaq
0034  * @version 1.0
0035  */
0036 class DarkProcessor : public QObject
0037 {
0038         Q_OBJECT
0039     public:
0040         explicit DarkProcessor(QObject *parent = nullptr);
0041 
0042         // Perform defect correction or dark subtraction
0043         void denoise(int trainID, ISD::CameraChip *targetChip, const QSharedPointer<FITSData> &targetData, double duration,
0044                      uint16_t offsetX, uint16_t offsetY);
0045 
0046 
0047     private:
0048 
0049         // Denoise Internal
0050         bool denoiseInternal(bool useDefect);
0051         void processDenoiseResult();
0052 
0053         ////////////////////////////////////////////////////////////////////////////////////////////////
0054         /// Subtraction Functions
0055         ////////////////////////////////////////////////////////////////////////////////////////////////
0056 
0057         /**
0058         * @brief subtractHelper Calls tempelated subtract function
0059         * @param darkData passes dark frame data to templerated subtract function.
0060         * @param lightData passes list frame data to templerated subtract function.
0061         * @param offsetX passes offsetX to templerated subtract function.
0062         * @param offsetY passes offsetY to templerated subtract function.
0063         */
0064         void subtractDarkData(const QSharedPointer<FITSData> &darkData, const QSharedPointer<FITSData> &lightData,
0065                               uint16_t offsetX, uint16_t offsetY);
0066 
0067         /**
0068         * @brief subtract Subtracts dark pixels from light pixels given the supplied parameters
0069         * @param darkData Dark frame data.
0070         * @param lightData Light frame data. The light frame data is modified in this process.
0071         * @param offsetX Only apply subtraction beyond offsetX in X-axis.
0072         * @param offsetY Only apply subtraction beyond offsetY in Y-axis.
0073         */
0074         template <typename T>
0075         void subtractInternal(const QSharedPointer<FITSData> &darkData, const QSharedPointer<FITSData> &lightData,
0076                               uint16_t offsetX, uint16_t offsetY);
0077 
0078         ////////////////////////////////////////////////////////////////////////////////////////////////
0079         /// Defect Map Functions
0080         ////////////////////////////////////////////////////////////////////////////////////////////////
0081 
0082         /**
0083         * @brief normalizeDefects Remove defects from LIGHT image by replacing bad pixels with a 3x3 median filter around
0084         * them.
0085         * @param defectMap Defect Map containing a list of hot and cold pixels.
0086         * @param lightData Target light data to remove noise from.
0087         * @param offsetX Only apply filtering beyond offsetX in X-axis.
0088         * @param offsetY Only apply filtering beyond offsetX in Y-axis.
0089         */
0090         void normalizeDefects(const QSharedPointer<DefectMap> &defectMap, const QSharedPointer<FITSData> &lightData,
0091                               uint16_t offsetX, uint16_t offsetY);
0092 
0093         template <typename T>
0094         void normalizeDefectsInternal(const QSharedPointer<DefectMap> &defectMap, const QSharedPointer<FITSData> &lightData,
0095                                       uint16_t offsetX, uint16_t offsetY);
0096 
0097         template <typename T>
0098         T median3x3Filter(uint16_t x, uint16_t y, uint32_t width, T *buffer);
0099 
0100     signals:
0101         void darkFrameCompleted(bool);
0102         void newLog(const QString &message);
0103 
0104     private:
0105         QFutureWatcher<bool> m_Watcher;
0106         struct
0107         {
0108             int trainID;
0109             ISD::CameraChip *targetChip;
0110             QSharedPointer<FITSData> targetData;
0111             double duration;
0112             uint16_t offsetX;
0113             uint16_t offsetY;
0114         } info;
0115 
0116 
0117         // Testing
0118         friend class ::TestDefects;
0119         friend class ::TestSubtraction;
0120 
0121 };
0122 
0123 }
0124