SourceXtractorPlusPlus  0.19
SourceXtractor++, the next generation SExtractor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CompactModelBase.icpp
Go to the documentation of this file.
1 /*
2  * CompactModelBase.icpp
3  *
4  * Created on: Aug 19, 2019
5  * Author: mschefer
6  */
7 
8 
9 #include <random>
10 
11 namespace ModelFitting {
12 
13 template<typename ImageType>
19  : ExtendedModel<ImageType>({}, x_scale, y_scale, rotation, width, height, x, y),
21 {
22  m_jacobian = Mat22(transform).GetTranspose();
23  m_inv_jacobian = m_jacobian.GetInverse();
24 }
25 
26 template<typename ImageType>
28  double s, c;
29 #if defined(__APPLE__)
30  __sincos(m_rotation->getValue(), &s, &c);
31 #elif defined(_GNU_SOURCE)
32  sincos(m_rotation->getValue(), &s, &c);
33 #else
34  s = sin(m_rotation->getValue());
35  c = cos(m_rotation->getValue());
36 #endif
37 
39  c, s,
40  -s, c);
41 
42  Mat22 scale(
43  1. / m_x_scale->getValue(), 0.0,
44  0.0, 1. / m_y_scale->getValue());
45 
46  return scale * rotation * m_inv_jacobian * pixel_scale;
47 }
48 
49 template<typename ImageType>
50 template<typename ModelEvaluator>
51 inline float CompactModelBase<ImageType>::samplePixel(const ModelEvaluator& model_eval, int x, int y, unsigned int subsampling) const {
52  double acc = 0.;
53  for (std::size_t ix=0; ix<subsampling; ++ix) {
54  float x_model = (x - 0.5 + (ix+1) * 1.0 / (subsampling+1));
55  for (std::size_t iy=0; iy<subsampling; ++iy) {
56  float y_model = (y - 0.5 + (iy+1) * 1.0 / (subsampling+1));
57  acc += model_eval.evaluateModel(x_model, y_model);
58  }
59  }
60 
61  return acc / (subsampling*subsampling);
62 }
63 
64 template<typename ImageType>
65 template<typename ModelEvaluator>
66 inline float CompactModelBase<ImageType>::sampleStochastic(const ModelEvaluator& model_eval, int x, int y, unsigned int samples) const {
67  double acc = 0.;
69  std::uniform_real_distribution<double> distribution(-.5,.5);
70 
71  for (unsigned int i=0; i<samples; i++) {
72  acc += model_eval.evaluateModel(double(x) + distribution(generator), double(y) + distribution(generator));
73  }
74 
75  return acc / samples;
76 }
77 
78 
79 
80 template<typename ImageType>
81 template<typename ModelEvaluator>
82 inline float CompactModelBase<ImageType>::adaptiveSamplePixel(const ModelEvaluator& model_eval, int x, int y, unsigned int max_subsampling, float threshold) const {
83  unsigned int steps[] = {1,3,5,7,11,15,23,31,47,63,95,127};
84  float value = samplePixel(model_eval, x,y, 1);
85  for (unsigned int i=2; i < (sizeof(steps)/sizeof(steps[0])) && steps[i] <= max_subsampling; i++) {
86  float newValue = samplePixel(model_eval, x,y, steps[i] + (max_subsampling % 2));
87 
88  double diff = fabs(newValue - value);
89  if (diff <= threshold * value) {
90  value = newValue;
91  break;
92  }
93 
94  value = newValue;
95  }
96 
97  return value;
98 }
99 
100 // computes the square of distance from origin to a line defined by 2 points
101 template<typename ImageType>
102 double CompactModelBase<ImageType>::computeSqrDistanceLineToOrigin(double x1, double y1, double x2, double y2) const {
103  double a = (x2-x1) * y1 - (y2-y1) * x1;
104  return a * a / ((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
105 }
106 
107 template<typename ImageType>
109 
110  // transform coordinates of 3 corner points of the rendering rectangle, to be in the same space the model is evaluated
111 
112  double x = size_x * 0.95f / 2.f;
113  double y = size_y * 0.95f / 2.f;
114 
115  double p0_x = x * transform[0] + y * transform[1];
116  double p0_y = x * transform[2] + y * transform[3];
117  double p1_x = -x * transform[0] + y * transform[1];
118  double p1_y = -x * transform[2] + y * transform[3];
119  double p2_x = x * transform[0] - y * transform[1];
120  double p2_y = x * transform[2] - y * transform[3];
121 
122  // Now computes distance from border lines in that space and use that as maximum radius to be evaluated
123 
124  return std::min(computeSqrDistanceLineToOrigin(p0_x, p0_y, p1_x, p1_y),
125  computeSqrDistanceLineToOrigin(p0_x, p0_y, p2_x, p2_y));
126 }
127 
128 template<typename ImageType>
129 void CompactModelBase<ImageType>::renormalize(ImageType& image, double flux) const {
131 
132  int width = Traits::width(image);
133  int height = Traits::height(image);
134 
135  double acc = 0.0;
136 
137  for (int y=0; y<height; y++) {
138  for (int x=0; x<width; x++) {
139  acc += Traits::at(image, x, y);
140  }
141  }
142 
143  if (acc > 0.0) {
144  double scale = flux / acc;
145  for (int y=0; y<height; y++) {
146  for (int x=0; x<width; x++) {
147  Traits::at(image, x, y) = Traits::at(image, x, y) * scale;
148  }
149  }
150  }
151 }
152 
153 }
float samplePixel(const ModelEvaluator &model_eval, int x, int y, unsigned int subsampling) const
Mat22 GetTranspose() const
Definition: Mat22.h:73
double getMaxRadiusSqr(std::size_t size_x, std::size_t size_y, const Mat22 &transform) const
T min(T...args)
T sin(T...args)
m_rotation(rotation)
Mat22 getCombinedTransform(double pixel_scale) const
constexpr double s
T cos(T...args)
float adaptiveSamplePixel(const ModelEvaluator &model_eval, int x, int y, unsigned int max_subsampling, float threshold=1.1) const
T fabs(T...args)
m_y_scale(y_scale)
void renormalize(ImageType &image, double flux) const
ModelFitting::ImageTraits< ImageInterfaceTypePtr > Traits
Mat22 GetInverse() const
Definition: Mat22.h:58
float sampleStochastic(const ModelEvaluator &model_eval, int x, int y, unsigned int samples=100) const
double computeSqrDistanceLineToOrigin(double x1, double y1, double x2, double y2) const
m_x_scale(x_scale)
const double pixel_scale
Definition: TestImage.cpp:74
std::pair< double, double > transform(int x, int y, const std::array< double, 4 > &t)
CompactModelBase(std::shared_ptr< BasicParameter > x_scale, std::shared_ptr< BasicParameter > y_scale, std::shared_ptr< BasicParameter > rotation, double width, double height, std::shared_ptr< BasicParameter > x, std::shared_ptr< BasicParameter > y, std::tuple< double, double, double, double > transform)