SatDump 2.0.0-alpha-520736c72
Loading...
Searching...
No Matches
channel_transform.h
Go to the documentation of this file.
1#pragma once
2
6
7#include "core/exception.h"
8#include "nlohmann/json.hpp"
9
10#include "projection/thinplatespline.h" // TODOREWORK Move to here?
11
12namespace satdump
13{
39 {
40 public:
41 enum transform_type_t
42 {
43 TYPE_INVALID = 0,
44 TYPE_NONE = 1,
45 TYPE_AFFINE = 2,
46 TYPE_AFFINE_SLANTX = 3,
47 TYPE_AFFINE_INTERPX = 4,
48 TYPE_INTERP_XY = 5,
49 };
50
51 private:
52 transform_type_t d_type = TYPE_INVALID;
53
54 double affine_a_x;
55 double affine_a_y;
56 double affine_b_x;
57 double affine_b_y;
58
59 double slantx_center;
60 double slantx_ampli;
61
62 std::vector<std::pair<double, double>> interpx_points;
63 std::vector<std::pair<std::pair<double, double>, std::pair<double, double>>> interp_xy_points;
64 std::shared_ptr<projection::VizGeorefSpline2D> interp_fwd_interpolator;
65 std::shared_ptr<projection::VizGeorefSpline2D> interp_rev_interpolator;
66
67 public:
73
81 ChannelTransform &init_affine(double a_x, double a_y, double b_x, double b_y);
82
92 ChannelTransform &init_affine_slantx(double a_x, double a_y, double b_x, double b_y, double slantx_center, double slantx_ampli);
93
102 ChannelTransform &init_affine_interpx(double a_x, double a_y, double b_x, double b_y, std::vector<std::pair<double, double>> interpx_points);
103
104 // TODOREWORK
105 ChannelTransform &init_interp_xy(std::vector<std::pair<std::pair<double, double>, std::pair<double, double>>> interp_xy_points);
106
107 public:
108 friend void to_json(nlohmann::json &j, const ChannelTransform &v)
109 {
110 j["type"] = (int)v.d_type;
111
112 if (v.d_type == TYPE_AFFINE || v.d_type == TYPE_AFFINE_SLANTX || v.d_type == TYPE_AFFINE_INTERPX)
113 {
114 j["ax"] = v.affine_a_x;
115 j["ay"] = v.affine_a_y;
116 j["bx"] = v.affine_b_x;
117 j["by"] = v.affine_b_y;
118 }
119
120 if (v.d_type == TYPE_AFFINE_SLANTX)
121 {
122 j["slantx_center"] = v.slantx_center;
123 j["slantx_ampli"] = v.slantx_ampli;
124 }
125
126 if (v.d_type == TYPE_AFFINE_INTERPX)
127 {
128 j["interpx_points"] = v.interpx_points; // v.fwd_interpolator.get_points();
129 }
130
131 if (v.d_type == TYPE_INTERP_XY)
132 {
133 j["interp_xy_points"] = v.interp_xy_points; // v.fwd_interpolator.get_points();
134 }
135 }
136
137 friend void from_json(const nlohmann::json &j, ChannelTransform &v)
138 {
139 v.d_type = (transform_type_t)j["type"].get<int>();
140
141 if (v.d_type == TYPE_AFFINE || v.d_type == TYPE_AFFINE_SLANTX || v.d_type == TYPE_AFFINE_INTERPX)
142 {
143 v.affine_a_x = j["ax"];
144 v.affine_a_y = j["ay"];
145 v.affine_b_x = j["bx"];
146 v.affine_b_y = j["by"];
147 }
148
149 if (v.d_type == TYPE_AFFINE_SLANTX)
150 {
151 v.slantx_center = j["slantx_center"];
152 v.slantx_ampli = j["slantx_ampli"];
153 }
154
155 if (v.d_type == TYPE_AFFINE_INTERPX)
156 {
157 v.interpx_points = j["interpx_points"].get<std::vector<std::pair<double, double>>>();
158
159 v.interp_fwd_interpolator = std::make_shared<projection::VizGeorefSpline2D>(1);
160 v.interp_rev_interpolator = std::make_shared<projection::VizGeorefSpline2D>(1);
161
162 for (auto &p : v.interpx_points)
163 {
164 v.interp_fwd_interpolator->add_point(p.first, p.first, &p.second);
165 v.interp_rev_interpolator->add_point(p.second, p.second, &p.first);
166 }
167
168 v.interp_fwd_interpolator->solve();
169 v.interp_rev_interpolator->solve();
170 }
171
172 if (v.d_type == TYPE_INTERP_XY)
173 {
174 v.interp_xy_points = j["interp_xy_points"].get<std::vector<std::pair<std::pair<double, double>, std::pair<double, double>>>>();
175
176 v.interp_fwd_interpolator = std::make_shared<projection::VizGeorefSpline2D>(2);
177 v.interp_rev_interpolator = std::make_shared<projection::VizGeorefSpline2D>(2);
178
179 for (auto &p : v.interp_xy_points)
180 {
181 printf("Point %f %f => %f %f\n", p.first.first, p.first.second, p.second.first, p.second.second);
182 double p1[2] = {p.second.first, p.second.second};
183 v.interp_fwd_interpolator->add_point(p.first.first, p.first.second, p1);
184 double p2[2] = {p.first.first, p.first.second};
185 v.interp_rev_interpolator->add_point(p.second.first, p.second.second, p2);
186 }
187
188 printf("%d %d\n", v.interp_fwd_interpolator->solve(), v.interp_rev_interpolator->solve());
189 }
190 }
191
196 transform_type_t getType();
197
202 void render();
203
204 public: // Must be inline for performance reasons!
210 inline void forward(double *x, double *y) const
211 {
212 if (d_type == TYPE_NONE)
213 ;
214 else if (d_type == TYPE_AFFINE)
215 {
216 *x = *x * affine_a_x + affine_b_x;
217 *y = *y * affine_a_y + affine_b_y;
218 }
219 else if (d_type == TYPE_AFFINE_SLANTX)
220 {
221 *y -= (*x - slantx_center) * slantx_ampli;
222 *x = *x * affine_a_x + affine_b_x;
223 *y = *y * affine_a_y + affine_b_y;
224 }
225 else if (d_type == TYPE_AFFINE_INTERPX)
226 {
227 *x = *x * affine_a_x + affine_b_x;
228 *y = *y * affine_a_y + affine_b_y;
229 interp_fwd_interpolator->get_point(*x, *x, x);
230 }
231 else if (d_type == TYPE_INTERP_XY)
232 {
233 double out[2]; // TODOREWORK
234 // printf("%f %f FWD => ", *x, *y);
235 interp_fwd_interpolator->get_point(*x, *y, out);
236 *x = out[0];
237 *y = out[1];
238 // printf("%f %f\n ", *x, *y);
239 }
240 else if (d_type == TYPE_INVALID)
241 throw satdump_exception("Invalid Channel Transform!\n");
242 }
243
249 inline void reverse(double *x, double *y) const
250 {
251 if (d_type == TYPE_NONE)
252 ;
253 else if (d_type == TYPE_AFFINE)
254 {
255 *x = (*x - affine_b_x) / affine_a_x;
256 *y = (*y - affine_b_y) / affine_a_y;
257 }
258 else if (d_type == TYPE_AFFINE_SLANTX)
259 {
260 *x = (*x - affine_b_x) / affine_a_x;
261 *y = (*y - affine_b_y) / affine_a_y;
262 *y += (*x - slantx_center) * slantx_ampli;
263 }
264 else if (d_type == TYPE_AFFINE_INTERPX)
265 {
266 interp_rev_interpolator->get_point(*x, *x, x);
267 *x = (*x - affine_b_x) / affine_a_x;
268 *y = (*y - affine_b_y) / affine_a_y;
269 }
270 else if (d_type == TYPE_INTERP_XY)
271 {
272 double out[2]; // TODOREWORK
273 printf("%f %f REV => ", *x, *y);
274 interp_rev_interpolator->get_point(*x, *y, out);
275 *x = out[0];
276 *y = out[1];
277 printf("%f %f\n ", *x, *y);
278 }
279 else if (d_type == TYPE_INVALID)
280 throw satdump_exception("Invalid Channel Transform!\n");
281 }
282 };
283} // namespace satdump
Class handling 2D transforms, mainly intended for image channels. This covers a simple but pretty imp...
Definition channel_transform.h:39
void render()
Render ImGui UI to edit the transform.
Definition channel_transform_render.cpp:6
ChannelTransform & init_affine_interpx(double a_x, double a_y, double b_x, double b_y, std::vector< std::pair< double, double > > interpx_points)
Initialize an AFFINE_INTERPX transform.
Definition channel_transform.cpp:38
void forward(double *x, double *y) const
Convert channel coordinates to reference coordinates.
Definition channel_transform.h:210
void reverse(double *x, double *y) const
Convert reference coordinates to channel coordinates.
Definition channel_transform.h:249
ChannelTransform & init_affine(double a_x, double a_y, double b_x, double b_y)
Initialize an AFFINE transform.
Definition channel_transform.cpp:16
ChannelTransform & init_none()
Initialize a NONE transform.
Definition channel_transform.cpp:10
transform_type_t getType()
Get type of this transform.
Definition channel_transform.cpp:5
ChannelTransform & init_affine_slantx(double a_x, double a_y, double b_x, double b_y, double slantx_center, double slantx_ampli)
Initialize an AFFINE_SLANTX transform.
Definition channel_transform.cpp:26