Wildmeshing Toolkit
Loading...
Searching...
No Matches
bicubic_interpolation.cpp
Go to the documentation of this file.
2
4
7 const size_t width,
8 const size_t height,
9 const float* buffer,
10 const double sx_,
11 const double sy_,
12 const WrappingMode mode_x,
13 const WrappingMode mode_y)
14{
16
17 const auto get_coordinate = [](const int x, const int size, const WrappingMode mode) -> int {
18 switch (mode) {
19 case WrappingMode::REPEAT: return (x + size) % size;
20
22 if (x < 0)
23 return -(x % size);
24 else if (x < size)
25 return x;
26 else
27 return size - 1 - (x - size) % size;
28 case WrappingMode::CLAMP_TO_EDGE: return std::clamp(x, 0, size - 1);
29 default: return (x + size) % size;
30 }
31 };
32 const auto get_buffer_value = [&](int xx, int yy) -> float {
33 xx = get_coordinate(xx, static_cast<int>(width), mode_x);
34 yy = get_coordinate(yy, static_cast<int>(height), mode_y);
35 const int index = (yy % height) * width + (xx % width);
36 return buffer[index];
37 };
38
39 const auto sx = static_cast<int>(std::floor(sx_ - 0.5));
40 const auto sy = static_cast<int>(std::floor(sy_ - 0.5));
41
42 samples(0) = get_buffer_value(sx - 1, sy - 1);
43 samples(1) = get_buffer_value(sx, sy - 1);
44 samples(2) = get_buffer_value(sx + 1, sy - 1);
45 samples(3) = get_buffer_value(sx + 2, sy - 1);
46
47 samples(4) = get_buffer_value(sx - 1, sy);
48 samples(5) = get_buffer_value(sx, sy);
49 samples(6) = get_buffer_value(sx + 1, sy);
50 samples(7) = get_buffer_value(sx + 2, sy);
51
52 samples(8) = get_buffer_value(sx - 1, sy + 1);
53 samples(9) = get_buffer_value(sx, sy + 1);
54 samples(10) = get_buffer_value(sx + 1, sy + 1);
55 samples(11) = get_buffer_value(sx + 2, sy + 1);
56
57 samples(12) = get_buffer_value(sx - 1, sy + 2);
58 samples(13) = get_buffer_value(sx, sy + 2);
59 samples(14) = get_buffer_value(sx + 1, sy + 2);
60 samples(15) = get_buffer_value(sx + 2, sy + 2);
61
62 return samples;
63}
64
66{
67 BicubicMatrix ope;
68 Eigen::Index row = 0;
69 for (float yy = -1; yy < 3; yy++)
70 for (float xx = -1; xx < 3; xx++) {
71 ope(row, 0) = 1;
72 ope(row, 1) = xx;
73 ope(row, 2) = xx * xx;
74 ope(row, 3) = xx * xx * xx;
75
76 ope(row, 4) = yy;
77 ope(row, 5) = xx * yy;
78 ope(row, 6) = xx * xx * yy;
79 ope(row, 7) = xx * xx * xx * yy;
80
81 ope(row, 8) = yy * yy;
82 ope(row, 9) = xx * yy * yy;
83 ope(row, 10) = xx * xx * yy * yy;
84 ope(row, 11) = xx * xx * xx * yy * yy;
85
86 ope(row, 12) = yy * yy * yy;
87 ope(row, 13) = xx * yy * yy * yy;
88 ope(row, 14) = xx * xx * yy * yy * yy;
89 ope(row, 15) = xx * xx * xx * yy * yy * yy;
90
91 row++;
92 }
93
94 {
95 std::stringstream ss;
96 ss << ope << std::endl;
97 logger().debug("ope det {}\n{}", ope.determinant(), ss.str());
98 }
99
100 // invert operator
101 BicubicMatrix ope_inv = ope.inverse();
102
103 // prune "zeros"
104 ope_inv = ope_inv.unaryExpr([](const float& xx) { return fabs(xx) < 1e-5f ? 0 : xx; });
105
106 {
107 std::stringstream ss;
108 ss << ope_inv << std::endl;
109 logger().debug("ope_inv det {}\n{}", ope_inv.determinant(), ss.str());
110 }
111
112 // double check inverse property
113 assert((ope * ope_inv - BicubicMatrix::Identity()).array().abs().maxCoeff() < 1e-5);
114
115 return ope_inv;
116}
117
119{
121 return mat;
122}
123} // namespace wmtk::components::adaptive_tessellation::image
BicubicVector< float > extract_samples(const size_t width, const size_t height, const float *buffer, const double sx_, const double sy_, const WrappingMode mode_x, const WrappingMode mode_y)
Rational abs(const Rational &r0)
Definition Rational.cpp:328
spdlog::logger & logger()
Retrieves the current logger.
Definition Logger.cpp:58