SourceXtractorPlusPlus 0.21
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
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
11namespace ModelFitting {
12
13template<typename ImageType>
14CompactModelBase<ImageType>::CompactModelBase(
15 std::shared_ptr<BasicParameter> x_scale, std::shared_ptr<BasicParameter> y_scale,
16 std::shared_ptr<BasicParameter> rotation, double width, double height,
17 std::shared_ptr<BasicParameter> x, std::shared_ptr<BasicParameter> y,
18 std::tuple<double, double, double, double> transform)
19 : ExtendedModel<ImageType>({}, x_scale, y_scale, rotation, width, height, x, y),
20 m_x_scale(x_scale), m_y_scale(y_scale), m_rotation(rotation)
21{
22 m_jacobian = Mat22(transform).GetTranspose();
23 m_inv_jacobian = m_jacobian.GetInverse();
24}
25
26template<typename ImageType>
27Mat22 CompactModelBase<ImageType>::getCombinedTransform(double pixel_scale) const {
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
38 Mat22 rotation(
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
49template<typename ImageType>
50template<typename ModelEvaluator>
51inline 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
64template<typename ImageType>
65template<typename ModelEvaluator>
66inline float CompactModelBase<ImageType>::sampleStochastic(const ModelEvaluator& model_eval, int x, int y, unsigned int samples) const {
67 double acc = 0.;
68 std::default_random_engine generator;
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
80template<typename ImageType>
81template<typename ModelEvaluator>
82inline 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
101template<typename ImageType>
102double 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
107template<typename ImageType>
108double CompactModelBase<ImageType>::getMaxRadiusSqr(std::size_t size_x, std::size_t size_y, const Mat22& transform) const {
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
128template<typename ImageType>
129void CompactModelBase<ImageType>::renormalize(ImageType& image, double flux) const {
130 using Traits = ImageTraits<ImageType>;
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}