mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
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#include "eigenImage.hpp"
31
33
34namespace mx
35{
36namespace improc
37{
38
39/// Find stars in an image by SNR thresholding
40/**
41 * \ingroup image_utils
42 */
43template <typename _realT>
45{
46
47 public:
48 typedef _realT realT; ///< The real valued type in which to do calculations
49
50 typedef std::pair<int, int> pixelT; ///< Pixel coordinates
51
52 protected:
53 realT m_threshold{ 5 }; ///< The SNR threshold to use
54
55 realT m_minsep{ 2 }; ///< The minimum separation between stars. Closer SNR detections are treated as the same star.
56
58 true }; ///< If true, then the median is used for standard deviation calculation. The mean is used otherwise.
59
60 // Working memory, retained to help with repeated calls.
61 std::vector<float> m_vals;
62 std::vector<pixelT> m_pixs;
63 std::vector<size_t> m_snr;
64
65 public:
66 /// Default c'tor
68
69 /// Constructor to set up the algorithm
70 sourceFinder( realT thresh, ///< [in]
71 realT minsep ///< [in]
72 );
73
74 /// Clear the working memory
75 void clear();
76
77 /// Set the SNR threshold
78 void treshold( const realT &thresh /**< [in] the new threshold*/ );
79
80 /// Get the SNR threshold
81 /** \returns the current value of m_threshold;
82 */
83 realT threshold();
84
85 /// Set the minimum separation
86 void minsep( const realT &msep /**< [in] the new minimum separation*/ );
87
88 /// Get the minimum separation between stars
89 /** \returns the current value of m_minsep;
90 */
91 realT minsep();
92
93 /// Set the useMedian flag
94 void useMedian( const bool &useMed /**< [in] the new useMedian flag value*/ );
95
96 /// Get the useMedian flag
97 /** \returns the current value of m_useMedian;
98 */
99 bool useMedian();
100
101 /// Find stars in an image
102 /** Returns the coordinates as (row, col) of the highest SNR pixel in each unique star.
103 *
104 * \returns a vector of pixel coordinates
105 */
106 std::vector<pixelT> operator()( const eigenImage<realT> &im /**< [in] the image to search for stars*/ );
107};
108
109template <typename realT>
113
114template <typename realT>
118
119template <typename realT>
121{
122 m_threshold = thresh;
123}
124
125template <typename realT>
127{
128 m_vals.clear();
129 m_pixs.clear();
130 m_snr.clear();
131}
132
133template <typename realT>
138
139template <typename realT>
141{
142 m_minsep = msep;
143}
144
145template <typename realT>
150
151template <typename realT>
152void sourceFinder<realT>::useMedian( const bool &useMed )
153{
154 m_useMedian = useMed;
155}
156
157template <typename realT>
159{
160 return m_useMedian;
161}
162
163template <typename realT>
164std::vector<typename sourceFinder<realT>::pixelT> sourceFinder<realT>::operator()( const eigenImage<realT> &im )
165{
166 m_vals.resize( im.rows() * im.cols() );
167 m_pixs.resize( im.rows() * im.cols() );
168
169 int p = 0;
170 for( int cc = 0; cc < im.cols(); ++cc )
171 {
172 for( int rr = 0; rr < im.rows(); ++rr )
173 {
174 m_vals[p] = im( rr, cc );
175 m_pixs[p] = { rr, cc };
176 ++p;
177 }
178 }
179
180 realT mm;
181
182 if( m_useMedian )
183 mm = math::vectorMedian( m_vals );
184 else
185 mm = math::vectorMean( m_vals );
186 realT std = sqrt( math::vectorVariance( m_vals, mm ) );
187
188 // Get the SNR for any pixels above the threshold
189 m_snr.clear();
190 for( size_t n = 0; n < m_vals.size(); ++n )
191 {
192 if( ( m_vals[n] - mm ) / std >= m_threshold )
193 {
194 m_snr.push_back( n );
195 }
196 }
197
198 // Delete the pixels above threshold which are with minsep of a higher pixel
199 realT mms2 = m_minsep * m_minsep; // save an op
200 for( long n = 0; n < m_snr.size(); ++n )
201 {
202 for( long m = 0; m < m_snr.size(); ++m )
203 {
204 if( m == n )
205 continue;
206
207 // Squared distance:
208 realT d2 = pow( m_pixs[m_snr[n]].first - m_pixs[m_snr[m]].first, 2 ) +
209 pow( m_pixs[m_snr[n]].second - m_pixs[m_snr[m]].second, 2 );
210
211 if( d2 < mms2 )
212 {
213 if( m_vals[m_snr[n]] < m_vals[m_snr[m]] ) // If this is the higher pixel, delete the lower
214 {
215 m_snr.erase( m_snr.begin() + n );
216 --n;
217 break; // So we're done comparing to the one we just deleted.
218 }
219 else // This is lower, so delete it.
220 {
221 m_snr.erase( m_snr.begin() + m );
222 if( m < n )
223 --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
std::pair< int, int > pixelT
Pixel coordinates.
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 minsep(const realT &msep)
Set the minimum separation.
void clear()
Clear the working memory.
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.
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 mxlib.hpp:37
Header for the std::vector utilities.