1 #ifndef CAMERARESPONSECURVE_H 2 #define CAMERARESPONSECURVE_H 6 #include <boost/filesystem.hpp> 10 #include <initializer_list> 23 template<
unsigned numLdrValues>
28 void writeToXML(tinyxml2::XMLElement *rootNode,
const char *nodeName)
const;
31 for (
unsigned i = 0; i < numLdrValues; i++)
32 m_hdrValues[i] = i * 2.0f / (numLdrValues - 1);
36 assert((values.size() == numLdrValues) &&
"Number of values in initializer list must match numLdrValues");
37 for (
unsigned i = 0; i < numLdrValues; i++)
38 m_hdrValues[i] = values.begin()[i];
41 float &ldrToHdr(
unsigned ldr) {
return m_hdrValues[ldr]; }
42 const float &ldrToHdr(
unsigned ldr)
const {
return m_hdrValues[ldr]; }
44 unsigned ldrFromHdr(
float hdr)
const;
46 float m_hdrValues[numLdrValues];
51 template<
unsigned numLdrValues>
61 void writeToXML(tinyxml2::XMLElement *node)
const;
62 void writeToXML(
const boost::filesystem::path &filename)
const;
68 template<
unsigned numLdrValues>
72 int max = numLdrValues-1;
74 int center = (max + min)/2;
75 float centerValue = m_hdrValues[center];
76 if (hdr < centerValue)
81 return std::max<int>(std::min<int>(min, numLdrValues-1), 0);
84 template<
unsigned ldrRange>
85 void computeCameraResponseFromMultipleExposures(
const std::vector<unsigned> &values,
const std::vector<float> &exposures,
float smoothness,
CameraResponseCurve<ldrRange> &curve)
87 assert(values.size() % exposures.size() == 0);
89 auto computeWeight = [](
unsigned v)->
float{
90 if (v == 0)
return 0.0f;
91 if (v == ldrRange-1)
return 0.0f;
95 const unsigned numMeasurements = values.size();
96 const unsigned numPixels = values.size() / exposures.size();
97 const unsigned numCurvatures = ldrRange-2;
98 Eigen::MatrixXd designMatrix(numMeasurements + numCurvatures + 1, numPixels + ldrRange);
99 designMatrix.setZero();
100 Eigen::VectorXd designVector(numMeasurements + numCurvatures + 1);
101 designVector.setZero();
102 for (
unsigned i = 0; i < numMeasurements; i++) {
103 unsigned pixel = i % numPixels;
104 unsigned image = i / numPixels;
106 float weight = computeWeight(values[image * numPixels + pixel]);
107 designVector[i] = std::log(exposures[image]) * weight;
109 designMatrix(i, pixel) = -1.0f * weight;
110 designMatrix(i, numPixels + values[image * numPixels + pixel]) = 1.0f * weight;
113 for (
unsigned i = 0; i < numCurvatures; i++) {
114 float weight = computeWeight(i+1);
115 designMatrix(numMeasurements+i, numPixels + i) = 1.0f * smoothness * weight;
116 designMatrix(numMeasurements+i, numPixels + i+1) = -2.0f * smoothness * weight;
117 designMatrix(numMeasurements+i, numPixels + i+2) = 1.0f * smoothness * weight;
118 designVector[numMeasurements+i] = 0.0f * smoothness * weight;
121 designMatrix(numMeasurements+numCurvatures, numPixels + ldrRange/2) = 1.0f;
122 designVector[numMeasurements+numCurvatures] = std::log(1.0f);
124 Eigen::VectorXd solution = designMatrix.jacobiSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(designVector);
126 for (
unsigned i = 0; i < ldrRange; i++)
127 curve.ldrToHdr(i) = std::exp(solution[numPixels+i]);
130 #ifdef SYB3R_HAS_EXIV2 132 void computeCameraResponseFromMultipleExposures(
const std::vector<std::string> &jpegFilenames,
unsigned numPixels,
float smoothness,
143 namespace Eos400D_neutral_3200K_artificial {
149 namespace Eos400D_neutral_7000K_shade {
160 #endif // CAMERARESPONSECURVE_H Definition: CameraPathEvaluation.cpp:10
Definition: CameraResponseCurve.h:52
Definition: CameraResponseCurve.h:24