SatDump 2.0.0-alpha-76a915210
Loading...
Searching...
No Matches
channel_transform.h
Go to the documentation of this file.
1#pragma once
2
6
7#include "nlohmann/json.hpp"
8#include "core/exception.h"
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 ||
113 v.d_type == TYPE_AFFINE_SLANTX ||
114 v.d_type == TYPE_AFFINE_INTERPX)
115 {
116 j["ax"] = v.affine_a_x;
117 j["ay"] = v.affine_a_y;
118 j["bx"] = v.affine_b_x;
119 j["by"] = v.affine_b_y;
120 }
121
122 if (v.d_type == TYPE_AFFINE_SLANTX)
123 {
124 j["slantx_center"] = v.slantx_center;
125 j["slantx_ampli"] = v.slantx_ampli;
126 }
127
128 if (v.d_type == TYPE_AFFINE_INTERPX)
129 {
130 j["interpx_points"] = v.interpx_points; // v.fwd_interpolator.get_points();
131 }
132
133 if (v.d_type == TYPE_INTERP_XY)
134 {
135 j["interp_xy_points"] = v.interp_xy_points; // v.fwd_interpolator.get_points();
136 }
137 }
138
139 friend void from_json(const nlohmann::json &j, ChannelTransform &v)
140 {
141 v.d_type = (transform_type_t)j["type"].get<int>();
142
143 if (v.d_type == TYPE_AFFINE ||
144 v.d_type == TYPE_AFFINE_SLANTX ||
145 v.d_type == TYPE_AFFINE_INTERPX)
146 {
147 v.affine_a_x = j["ax"];
148 v.affine_a_y = j["ay"];
149 v.affine_b_x = j["bx"];
150 v.affine_b_y = j["by"];
151 }
152
153 if (v.d_type == TYPE_AFFINE_SLANTX)
154 {
155 v.slantx_center = j["slantx_center"];
156 v.slantx_ampli = j["slantx_ampli"];
157 }
158
159 if (v.d_type == TYPE_AFFINE_INTERPX)
160 {
161 v.interpx_points = j["interpx_points"].get<std::vector<std::pair<double, double>>>();
162
163 v.interp_fwd_interpolator = std::make_shared<projection::VizGeorefSpline2D>(1);
164 v.interp_rev_interpolator = std::make_shared<projection::VizGeorefSpline2D>(1);
165
166 for (auto &p : v.interpx_points)
167 {
168 v.interp_fwd_interpolator->add_point(p.first, p.first, &p.second);
169 v.interp_rev_interpolator->add_point(p.second, p.second, &p.first);
170 }
171
172 v.interp_fwd_interpolator->solve();
173 v.interp_rev_interpolator->solve();
174 }
175
176 if (v.d_type == TYPE_INTERP_XY)
177 {
178 v.interp_xy_points = j["interp_xy_points"].get<std::vector<std::pair<std::pair<double, double>, std::pair<double, double>>>>();
179
180 v.interp_fwd_interpolator = std::make_shared<projection::VizGeorefSpline2D>(2);
181 v.interp_rev_interpolator = std::make_shared<projection::VizGeorefSpline2D>(2);
182
183 for (auto &p : v.interp_xy_points)
184 {
185 printf("Point %f %f => %f %f\n", p.first.first, p.first.second, p.second.first, p.second.second);
186 double p1[2] = {p.second.first, p.second.second};
187 v.interp_fwd_interpolator->add_point(p.first.first, p.first.second, p1);
188 double p2[2] = {p.first.first, p.first.second};
189 v.interp_rev_interpolator->add_point(p.second.first, p.second.second, p2);
190 }
191
192 v.interp_fwd_interpolator->solve();
193 v.interp_rev_interpolator->solve();
194 }
195 }
196
201 transform_type_t getType();
202
207 void render();
208
209 public: // Must be inline for performance reasons!
215 inline void forward(double *x, double *y) const
216 {
217 if (d_type == TYPE_NONE)
218 ;
219 else if (d_type == TYPE_AFFINE)
220 {
221 *x = *x * affine_a_x + affine_b_x;
222 *y = *y * affine_a_y + affine_b_y;
223 }
224 else if (d_type == TYPE_AFFINE_SLANTX)
225 {
226 *y -= (*x - slantx_center) * slantx_ampli;
227 *x = *x * affine_a_x + affine_b_x;
228 *y = *y * affine_a_y + affine_b_y;
229 }
230 else if (d_type == TYPE_AFFINE_INTERPX)
231 {
232 *x = *x * affine_a_x + affine_b_x;
233 *y = *y * affine_a_y + affine_b_y;
234 interp_fwd_interpolator->get_point(*x, *x, x);
235 }
236 else if (d_type == TYPE_INTERP_XY)
237 {
238 double out[2]; // TODOREWORK
239 printf("%f %f FWD => ", *x, *y);
240 interp_fwd_interpolator->get_point(*x, *y, out);
241 *x = out[0];
242 *y = out[1];
243 printf("%f %f\n ", *x, *y);
244 }
245 else if (d_type == TYPE_INVALID)
246 throw satdump_exception("Invalid Channel Transform!\n");
247 }
248
254 inline void reverse(double *x, double *y) const
255 {
256 if (d_type == TYPE_NONE)
257 ;
258 else if (d_type == TYPE_AFFINE)
259 {
260 *x = (*x - affine_b_x) / affine_a_x;
261 *y = (*y - affine_b_y) / affine_a_y;
262 }
263 else if (d_type == TYPE_AFFINE_SLANTX)
264 {
265 *x = (*x - affine_b_x) / affine_a_x;
266 *y = (*y - affine_b_y) / affine_a_y;
267 *y += (*x - slantx_center) * slantx_ampli;
268 }
269 else if (d_type == TYPE_AFFINE_INTERPX)
270 {
271 interp_rev_interpolator->get_point(*x, *x, x);
272 *x = (*x - affine_b_x) / affine_a_x;
273 *y = (*y - affine_b_y) / affine_a_y;
274 }
275 else if (d_type == TYPE_INTERP_XY)
276 {
277 double out[2]; // TODOREWORK
278 printf("%f %f REV => ", *x, *y);
279 interp_rev_interpolator->get_point(*x, *y, out);
280 *x = out[0];
281 *y = out[1];
282 printf("%f %f\n ", *x, *y);
283 }
284 else if (d_type == TYPE_INVALID)
285 throw satdump_exception("Invalid Channel Transform!\n");
286 }
287 };
288}
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:215
void reverse(double *x, double *y) const
Convert reference coordinates to channel coordinates.
Definition channel_transform.h:254
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