File indexing completed on 2024-05-12 15:23:44
0001 /* 0002 SPDX-FileCopyrightText: 2020 Hy Murveit <hy@murveit.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QObject> 0010 #include <QList> 0011 #include <QVector> 0012 #include <QVector2D> 0013 0014 #include "fitsviewer/fitsdata.h" 0015 #include "vect.h" 0016 0017 /* 0018 * This class is useful to track a guide star by noting its position relative to other stars. 0019 * It is intended to be resilient to translation, a bit of positional noise, and slight field rotation. 0020 * The class is initialized with a set of reference (x,y) positions from stars, where one is 0021 * designated a guide star. Then, given a set of new input star positions, it determines a mapping 0022 * of the new stars to the references. Some reference stars may not be in the new star group, and 0023 * there may be new stars that don't appear in the references. However, the guide star must appear 0024 * in both sets for this to be successful. 0025 */ 0026 0027 class StarCorrespondence 0028 { 0029 public: 0030 // Initializes with reference stars. 0031 // One of the stars with index guideStar is a special "guide star". 0032 StarCorrespondence(const QList<Edge> &stars, int guideStar); 0033 StarCorrespondence(); 0034 ~StarCorrespondence() {} 0035 0036 // If the default constructor was called, then initialize must be called with the 0037 // reference star positions and the index in stars of the guideStar. 0038 void initialize(const QList<Edge> &stars, int guideStar); 0039 0040 // Clears the references. 0041 void reset(); 0042 0043 // Associate the input stars with the reference stars. 0044 // StarMap[i] will contain the index of a reference star that corresponds to the ith star. 0045 // Some input stars may have no reference (starMap->at(i) == -1), and some references may 0046 // not correspond to any input stars. There will be no star-reference mapping with 0047 // distance longer than maxDistance. If adapt is true, the input positions are used 0048 // to incrementally adapt the reference positions. 0049 Edge find(const QList<Edge> &stars, double maxDistance, QVector<int> *starMap, bool adapt = true, double minFraction = 0.5); 0050 0051 // Returns the number of reference stars. 0052 int size() const 0053 { 0054 return references.size(); 0055 } 0056 0057 // Return a reference to the ith reference star. Caller's responsiblity 0058 // to make sure i >= 0 && i < references.size(); 0059 // Recompute the reference coordinates as we may adapt them. 0060 Edge reference(int i) const 0061 { 0062 Edge star = references[i]; 0063 star.x = references[guideStarIndex].x + guideStarOffsets[i].x; 0064 star.y = references[guideStarIndex].y + guideStarOffsets[i].y; 0065 return star; 0066 } 0067 QVector2D offset(int i) const 0068 { 0069 QVector2D offset; 0070 offset.setX(guideStarOffsets[i].x); 0071 offset.setY(guideStarOffsets[i].y); 0072 return offset; 0073 } 0074 0075 int guideStar() const 0076 { 0077 return guideStarIndex; 0078 } 0079 0080 void setAllowMissingGuideStar(bool value = true) 0081 { 0082 allowMissingGuideStar = value; 0083 } 0084 0085 void setImageSize(int width, int height) 0086 { 0087 imageWidth = width; 0088 imageHeight = height; 0089 } 0090 0091 int getNumReferencesFound() const 0092 { 0093 return m_NumReferencesFound; 0094 } 0095 0096 private: 0097 // The Offsets structure is used to keep the positions of the reference stars 0098 // relative to the guide star. 0099 struct Offsets 0100 { 0101 double x; // The x position of the star (in pixels), relative to the guide star. 0102 double y; // The y position of the star (in pixels), relative to the guide star. 0103 0104 Offsets(double x_, double y_) : x(x_), y(y_) {} 0105 Offsets() : x(0), y(0) {} // RPi compiler required this constructor. 0106 }; 0107 0108 // Update the reference-star offsets given the new star positions. 0109 // The adaption is similar to a 25-sample moving average. 0110 void initializeAdaptation(); 0111 void adaptOffsets(const QList<Edge> &stars, const QVector<int> &starMap); 0112 0113 // Utility used by find. Useful for iterating when the guide star is missing. 0114 int findInternal(const QList<Edge> &stars, double maxDistance, QVector<int> *starMap, 0115 int guideStarIndex, const QVector<Offsets> &offsets, 0116 int *numFound, int *numNotFound, double minFraction) const; 0117 0118 // Used to when guide star is missing. Creates offsets as if other stars were the guide star. 0119 void makeOffsets(const QVector<Offsets> &offsets, QVector<Offsets> *targetOffsets, int targetStar) const; 0120 0121 // When the guide star is missing, but star correspondence was successful, use the positions 0122 // of the stars that were found to create a virtual guide star--inferring a guide star position 0123 // using the offsets from the (unfound) guide star to the stars that were found. 0124 // Offsets are offsets that were created for a new "substitude guide star". 0125 // StarMap is the map made for that substitude by findInternal(). 0126 // Offset is the offset from the original guide star to that substitute guide star. 0127 Edge inventStarPosition(const QList<Edge> &stars, const QVector<int> &starMap, 0128 QVector<Offsets> offsets, Offsets offset) const; 0129 0130 // Finds the star closest to x,y. Returns the index in sortedStars. 0131 // sortedStars should be sorted in x, which allows for a speedup in search. 0132 int findClosestStar(double x, double y, const QList<Edge> sortedStars, 0133 double maxDistance, double *distance) const; 0134 0135 // The offsets of the reference stars relative to the guide star. 0136 QVector<Offsets> guideStarOffsets; 0137 0138 // Size stats for the reference stars. 0139 QVector<float> referenceSums; 0140 QVector<float> referenceNumPixels; 0141 0142 QList<Edge> references; // The original reference stars. 0143 int guideStarIndex; // The index of the guide star in references. 0144 bool initialized = false; // Set to true once the references and guideStar index has been set. 0145 0146 // If this is true, it will attempt star correspondence even if the guide star is missing. 0147 bool allowMissingGuideStar { false }; 0148 0149 // IIR filter parameter used to adapt offsets. 0150 double alpha; 0151 0152 // Setting imageWidth and height can speed up searching for stars in an image 0153 // by eliminating positions far outside the image. 0154 int imageWidth { 100000000 }; 0155 int imageHeight { 100000000 }; 0156 0157 // Number of references found in last call to find(). 0158 int m_NumReferencesFound { 0 }; 0159 0160 // A copy of the original reference offsets used so that the values don't move too far. 0161 QVector<Offsets> originalGuideStarOffsets; 0162 }; 0163