mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
sourceFinder.hpp
Go to the documentation of this file.
1 /** \file sourceFinder.hpp
2  * \brief Declares and defines a class for finding sources in images
3  * \ingroup image_processing_files
4  * \author Jared R. Males (jaredmales@gmail.com)
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2021 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 #ifndef improc_sourceFinder_hpp
28 #define improc_sourceFinder_hpp
29 
30 
31 #include "eigenImage.hpp"
32 
33 #include "../math/vectorUtils.hpp"
34 
35 namespace mx
36 {
37 namespace improc
38 {
39 
40 /// Find stars in an image by SNR thresholding
41 /**
42  * \ingroup image_utils
43  */
44 template<typename _realT>
46 {
47 
48 public:
49  typedef _realT realT; ///< The real valued type in which to do calculations
50 
51  typedef std::pair<int,int> pixelT; ///< Pixel coordinates
52 
53 protected:
54 
55  realT m_threshold {5}; ///< The SNR threshold to use
56 
57  realT m_minsep {2}; ///< The minimum separation between stars. Closer SNR detections are treated as the same star.
58 
59  bool m_useMedian {true}; ///< If true, then the median is used for standard deviation calculation. The mean is used otherwise.
60 
61  //Working memory, retained to help with repeated calls.
62  std::vector<float> m_vals;
63  std::vector<pixelT> m_pixs;
64  std::vector<size_t> m_snr;
65 
66 public:
67 
68  /// Default c'tor
69  sourceFinder();
70 
71  /// Constructor to set up the algorithm
72  sourceFinder( realT thresh, ///< [in]
73  realT minsep ///< [in]
74  );
75 
76  /// Clear the working memory
77  void clear();
78 
79  /// Set the SNR threshold
80  void treshold( const realT & thresh /**< [in] the new threshold*/ );
81 
82  /// Get the SNR threshold
83  /** \returns the current value of m_threshold;
84  */
85  realT threshold();
86 
87  /// Set the minimum separation
88  void minsep( const realT & msep /**< [in] the new minimum separation*/ );
89 
90  /// Get the minimum separation between stars
91  /** \returns the current value of m_minsep;
92  */
93  realT minsep();
94 
95  /// Set the useMedian flag
96  void useMedian( const bool & useMed /**< [in] the new useMedian flag value*/ );
97 
98  /// Get the useMedian flag
99  /** \returns the current value of m_useMedian;
100  */
101  bool useMedian();
102 
103  /// Find stars in an image
104  /** Returns the coordinates as (row, col) of the highest SNR pixel in each unique star.
105  *
106  * \returns a vector of pixel coordinates
107  */
108  std::vector<pixelT> operator()( const eigenImage<realT> & im /**< [in] the image to search for stars*/ );
109 
110 };
111 
112 template<typename realT>
114 {
115 }
116 
117 template<typename realT>
119  realT minsep
120  ) : m_threshold(thresh), m_minsep(minsep)
121 {
122 }
123 
124 template<typename realT>
126 {
127  m_threshold = thresh;
128 }
129 
130 template<typename realT>
132 {
133  m_vals.clear();
134  m_pixs.clear();
135  m_snr.clear();
136 }
137 
138 template<typename realT>
140 {
141  return m_threshold;
142 }
143 
144 template<typename realT>
146 {
147  m_minsep = msep;
148 }
149 
150 template<typename realT>
152 {
153  return m_minsep;
154 }
155 
156 template<typename realT>
157 void sourceFinder<realT>::useMedian(const bool & useMed)
158 {
159  m_useMedian = useMed;
160 }
161 
162 template<typename realT>
164 {
165  return m_useMedian;
166 }
167 
168 template<typename realT>
169 std::vector<typename sourceFinder<realT>::pixelT> sourceFinder<realT>::operator()( const eigenImage<realT> & im )
170 {
171  m_vals.resize(im.rows()*im.cols());
172  m_pixs.resize(im.rows()*im.cols());
173 
174  int p =0;
175  for(int cc=0;cc<im.cols();++cc)
176  {
177  for(int rr=0;rr<im.rows();++rr)
178  {
179  m_vals[p] = im(rr,cc);
180  m_pixs[p] = {rr,cc};
181  ++p;
182  }
183  }
184 
185  realT mm;
186 
187  if(m_useMedian) mm = math::vectorMedian(m_vals);
188  else mm = math::vectorMean(m_vals);
189  realT std = sqrt(math::vectorVariance(m_vals, mm));
190 
191  //Get the SNR for any pixels above the threshold
192  m_snr.clear();
193  for(size_t n=0; n < m_vals.size(); ++n)
194  {
195  if( (m_vals[n]-mm) / std >= m_threshold )
196  {
197  m_snr.push_back(n);
198  }
199  }
200 
201  //Delete the pixels above threshold which are with minsep of a higher pixel
202  realT mms2 = m_minsep*m_minsep; //save an op
203  for(long n =0; n < m_snr.size(); ++n)
204  {
205  for(long m=0; m < m_snr.size(); ++m)
206  {
207  if(m == n) continue;
208 
209  //Squared distance:
210  realT d2 = pow( m_pixs[m_snr[n]].first - m_pixs[m_snr[m]].first,2) + pow( m_pixs[m_snr[n]].second - m_pixs[m_snr[m]].second,2);
211 
212  if(d2 < mms2)
213  {
214  if( m_vals[m_snr[n]] < m_vals[m_snr[m]] ) //If this is the higher pixel, delete the lower
215  {
216  m_snr.erase(m_snr.begin() + n);
217  --n;
218  break; //So we're done comparing to the one we just deleted.
219  }
220  else //This is lower, so delete it.
221  {
222  m_snr.erase(m_snr.begin() + m);
223  if(m < n) --n; //changing size behind
224  --m;
225  continue;
226  }
227  }
228  }
229  }
230 
231  std::vector<pixelT> found(m_snr.size());
232 
233  for(size_t n = 0; n < m_snr.size(); ++n)
234  {
235  found[n] = m_pixs[m_snr[n]];
236  }
237 
238  return found;
239 }
240 
241 } //namespace improc
242 } //namespace mx
243 
244 #endif // improc_sourceFinder_hpp
Find stars in an image by SNR thresholding.
realT minsep()
Get the minimum separation between stars.
realT m_threshold
The SNR threshold to use.
realT m_minsep
The minimum separation between stars. Closer SNR detections are treated as the same star.
bool useMedian()
Get the useMedian flag.
sourceFinder()
Default c'tor.
bool m_useMedian
If true, then the median is used for standard deviation calculation. The mean is used otherwise.
std::vector< pixelT > operator()(const eigenImage< realT > &im)
Find stars in an image.
void treshold(const realT &thresh)
Set the SNR threshold.
_realT realT
The real valued type in which to do calculations.
realT threshold()
Get the SNR threshold.
void clear()
Clear the working memory.
std::pair< int, int > pixelT
Pixel coordinates.
Tools for using the eigen library for image processing.
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
Definition: eigenImage.hpp:44
valueT vectorMean(const valueT *vec, size_t sz)
Calculate the mean of a vector.
valueT vectorVariance(const valueT *vec, size_t sz, valueT mean)
Calculate the variance of a vector relative to a supplied mean value.
vectorT::value_type vectorMedian(const vectorT &vec, vectorT *work=0)
Calculate median of a vector, leaving the vector unaltered.
The mxlib c++ namespace.
Definition: mxError.hpp:107