mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
circleOuterpix.hpp
Go to the documentation of this file.
1 /** \file circleOuterpix.hpp
2  * \brief Declares and defines a class for finding the edge of a circle mask
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_circleOuterpix_hpp
28 #define improc_circleOuterpix_hpp
29 
30 
31 #include "eigenImage.hpp"
32 
33 #include "imageUtils.hpp"
34 
35 namespace mx
36 {
37 namespace improc
38 {
39 
40 /// Find the center and the outermost pixels of a circular mask, giving an estimate of the radius
41 /** Takes a 1/0 mask of a filled circle or annulus, and calculates the center coordinate by
42  * center-of-light, then finds the outermost 1 pixel in each row and column. Calculates the average radius
43  * of these pixels w.r.t. to the c.o.l. coords, as well as w.r.t. the average coords of the outer pixels
44  * themselves.
45  *
46  * Also produces an image containing the outer pixels.
47  *
48  * \returns 0 on success
49  *
50  * \tparam realT the real floating-point type for calculations
51  *
52  * \ingroup image_utils
53  *
54  */
55 template<typename realT>
56 int circleOuterpix( realT & x0, /// < [out] x coord of center of the mask by center-of-light
57  realT & y0, /// < [out] y coord of center of the mask by center-of-light
58  realT & avgr0, /// < [out] average radius of edge pixels w.r.t. center-of-light
59  realT & avgx, /// < [out] x coord of center of the mask by average edge pixel
60  realT & avgy, /// < [out] y coord of center of the mask by average edge pixel
61  realT & avgr, /// < [out] average radius of edge pixels w.r.t. to average edge pixel
62  eigenImage<realT> & circ, /// < [out] image showing the edge pixels with value 1, all other pixels 0. Resized.
63  const eigenImage<realT> & masked /// < [in] an image with a (roughly) circular mask of 1s
64  )
65 {
66 
67  circ.resize(masked.rows(), masked.cols());
68  circ.setZero();
69 
70  mx::improc::imageCenterOfLight(x0, y0, masked);
71 
72  for(size_t i=0; i< masked.rows(); ++i)
73  {
74  realT ndy =0;
75  realT pdy = 0;
76 
77  int nj = -1;
78  int pj = -1;
79 
80  for(size_t j=0; j<masked.cols(); ++j)
81  {
82  if(masked(i,j) == 1)
83  {
84  if(j-y0 < ndy)
85  {
86  ndy = j-y0;
87  nj = j;
88  }
89  if(j-y0 > pdy)
90  {
91  pdy = j-y0;
92  pj = j;
93  }
94  }
95  }
96 
97  if(nj != -1) circ(i,nj) = 1;
98  if(pj != -1) circ(i,pj) = 1;
99  }
100 
101  for(size_t j=0; j< masked.cols(); ++j)
102  {
103  realT ndx =0;
104  realT pdx = 0;
105 
106  int ni = -1;
107  int pi = -1;
108 
109  for(size_t i=0; i<masked.rows(); ++i)
110  {
111  if(masked(i,j) == 1)
112  {
113  if(i-x0 < ndx)
114  {
115  ndx = i-x0;
116  ni = i;
117  }
118  if(i-x0 > pdx)
119  {
120  pdx = i-x0;
121  pi = i;
122  }
123  }
124  }
125 
126  if(ni != -1) circ(ni,j) = 1;
127  if(pi != -1) circ(pi,j) = 1;
128  }
129 
130  int npix = 0;
131  avgx = 0;
132  avgy = 0;
133 
134  for(size_t i = 0; i < masked.rows(); ++i)
135  {
136  for(size_t j = 0; j < (size_t) masked.cols(); ++j)
137  {
138  if(circ(i,j) == 1)
139  {
140  ++npix;
141  avgx += i;
142  avgy += j;
143  }
144  }
145  }
146 
147  avgx /= npix;
148  avgy /= npix;
149 
150  avgr = 0;
151  avgr0 = 0;
152  for(size_t i = 0; i < (size_t) circ.rows(); ++i)
153  {
154  for(size_t j = 0; j < (size_t) circ.cols(); ++j)
155  {
156  if(circ(i,j) == 1)
157  {
158  avgr += sqrt( pow(i-avgx,2) + pow(j-avgy,2));
159  avgr0 += sqrt( pow(i-x0,2) + pow(j-y0,2));
160  }
161  }
162  }
163 
164  avgr /= npix;
165  avgr0 /= npix;
166 
167  return 0;
168 
169 }
170 
171 } //namespace improc
172 } //namespace mx
173 
174 #endif // improc_circleOuterpix_hpp
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
constexpr T pi()
Get the value of pi.
Definition: constants.hpp:52
int circleOuterpix(realT &x0, realT &y0, realT &avgr0, realT &avgx, realT &avgy, realT &avgr, eigenImage< realT > &circ, const eigenImage< realT > &masked)
Find the center and the outermost pixels of a circular mask, giving an estimate of the radius.
int imageCenterOfLight(typename imageT::Scalar &x, typename imageT::Scalar &y, const imageT &im)
Calculate the center of light of an image.
Definition: imageUtils.hpp:163
Header for the image processing utilities.
The mxlib c++ namespace.
Definition: mxError.hpp:107