1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Copyright (c) 2012-2017 VideoStitch SAS
// Copyright (c) 2018 stitchEm
#ifndef EMOR_HPP_
#define EMOR_HPP_
#include "config.hpp"
#include <array>
namespace VideoStitch {
namespace Core {
#if (_MSC_VER && _MSC_VER < 1900)
#define VS_CONSTEXPR
#else
#define VS_CONSTEXPR constexpr
#endif
/**
* A base response curve.
*/
class VS_EXPORT ResponseCurve {
public:
/**
* The size of the lookup table for one direction.
*/
static VS_CONSTEXPR int lutSize() { return 1024; }
/**
* The total size of the lookup table (both directions).
*/
static VS_CONSTEXPR int totalLutSize() {
// additional value for fast interpolation of the last value
return 2 * lutSize() + 1;
}
virtual ~ResponseCurve();
/**
* Returns the response curve.
* The first 1024 values are the direct response, the next 1024 values are the inverse response.
* Values are in [0,1].
*/
const float* getResponseCurve() const;
/**
* Returns the inverse response curve.
* Pointer to the 1024 values of the inverse response (second half of getResponseCurve).
* Values are in [0,1].
*/
const float* getInverseResponseCurve() const;
/**
* Takes the reciprocal of the curve.
*/
void invert();
/**
* How much did makeMonotonous() have to correct on creation?
*/
int getMonotonyError() const;
protected:
ResponseCurve();
/**
* Fill in the elements LutSize..(2 * LutSize - 1) with the inverse response.
*/
void computeInverseResponse();
/**
* The response curve.
*/
float* responseCurve;
private:
ResponseCurve(const ResponseCurve&);
/**
* Makes sure that the forward response is monotonous.
*/
void makeMonotonous();
/**
* Before making the curve monotonous, calculate how far off it was
*/
void calculateMonotonyError();
int monotonyError;
};
class ValueResponseCurve : public ResponseCurve {
public:
explicit ValueResponseCurve(const std::array<uint16_t, 256>& values);
};
/**
* A response curve that uses the first 6 eigenvectors of the EMoR model.
*/
class VS_EXPORT EmorResponseCurve : public ResponseCurve {
public:
/**
* Builds an response curve with the specified EMoR coefficients (coordinates in the EMoR basis).
* @param emor1: Coefficient for eigenvector 1.
* @param emor2: Coefficient for eigenvector 2.
* @param emor3: Coefficient for eigenvector 3.
* @param emor4: Coefficient for eigenvector 4.
* @param emor5: Coefficient for eigenvector 5.
*/
EmorResponseCurve(double emor1, double emor2, double emor3, double emor4, double emor5);
};
/**
* A response curve that uses the first 6 eigenvectors of the inverse EMoR model.
*/
class VS_EXPORT InvEmorResponseCurve : public ResponseCurve {
public:
/**
* Builds an response curve with the specified EMoR coefficients (coordinates in the inverse EMoR basis).
* @param emor1: Coefficient for eigenvector 1.
* @param emor2: Coefficient for eigenvector 2.
* @param emor3: Coefficient for eigenvector 3.
* @param emor4: Coefficient for eigenvector 4.
* @param emor5: Coefficient for eigenvector 5.
*/
InvEmorResponseCurve(double emor1, double emor2, double emor3, double emor4, double emor5);
};
} // namespace Core
} // namespace VideoStitch
#undef VS_CONSTEXPR
#endif