Skip to content

Commit

Permalink
[hdr] Adapt weight curves to method
Browse files Browse the repository at this point in the history
  • Loading branch information
ToukL committed Jun 7, 2019
1 parent 7e53368 commit 97455ef
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 30 deletions.
29 changes: 13 additions & 16 deletions src/aliceVision/hdr/GrossbergCalibrate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ namespace aliceVision {
namespace hdr {


GrossbergCalibrate::GrossbergCalibrate(const unsigned int dimension, const std::size_t channelQuantization)
GrossbergCalibrate::GrossbergCalibrate(const unsigned int dimension)
{
_dimension = dimension;
_channelQuantization = channelQuantization;
}

void GrossbergCalibrate::process(const std::vector< std::vector< image::Image<image::RGBfColor> > > &ldrImageGroups,
const std::size_t channelQuantization,
const std::vector< std::vector<float> > &times,
const int nbPoints,
const rgbCurve &weight,
Expand All @@ -38,20 +38,19 @@ void GrossbergCalibrate::process(const std::vector< std::vector< image::Image<im
static const std::size_t channels = 3;

//initialize response with g0 from invEmor
response = rgbCurve(_channelQuantization);
rgbCurve temporaryResponse(_channelQuantization);
response = rgbCurve(channelQuantization);
const double* ptrf0 = getEmorInvCurve(0);
std::vector<double> f0;
f0.assign(ptrf0, ptrf0 + _channelQuantization);
f0.assign(ptrf0, ptrf0 + channelQuantization);

Mat H(_channelQuantization, _dimension);
Mat H(channelQuantization, _dimension);
std::vector<double> hCurves[_dimension];

for(unsigned int i=0; i<_dimension; ++i)
{
const double *h = getEmorInvCurve(i+1);
hCurves[i].assign(h, h + _channelQuantization);
H.col(i) = Eigen::Map<Vec>(hCurves[i].data(), _channelQuantization);
hCurves[i].assign(h, h + channelQuantization);
H.col(i) = Eigen::Map<Vec>(hCurves[i].data(), channelQuantization);
}

for(unsigned int g=0; g<ldrImageGroups.size(); ++g)
Expand All @@ -66,7 +65,7 @@ void GrossbergCalibrate::process(const std::vector< std::vector< image::Image<im

for(unsigned int channel=0; channel<channels; ++channel)
{
temporaryResponse.getCurve(channel) = std::vector<float>(f0.begin(), f0.end());
response.getCurve(channel) = std::vector<float>(f0.begin(), f0.end());

Mat A = Mat::Zero(nbPoints*(nbImages-1), _dimension);
Vec b = Vec::Zero(nbPoints*(nbImages-1));
Expand All @@ -84,8 +83,10 @@ void GrossbergCalibrate::process(const std::vector< std::vector< image::Image<im
{
double sample1 = std::max(0.f, std::min(1.f, image1(step*l)(channel)));
double sample2 = std::max(0.f, std::min(1.f, image2(step*l)(channel)));
std::size_t index1 = std::round((_channelQuantization-1) * sample1);
std::size_t index2 = std::round((_channelQuantization-1) * sample2);


std::size_t index1 = std::round((channelQuantization-1) * sample1);
std::size_t index2 = std::round((channelQuantization-1) * sample2);

// double w = std::min(weight(sample1, channel), weight(sample2, channel));

Expand All @@ -98,8 +99,6 @@ void GrossbergCalibrate::process(const std::vector< std::vector< image::Image<im
// double w = (w_R + w_G + w_B) / 3.0;
// double w = (w_R * w_G * w_B);
// double w = std::min(std::min(w_R, w_G), w_B);
// if(std::max(sample1, sample2) > 0.95)
// w = 0.0;

b(j*nbPoints + l) = w * (f0.at(index2) - k * f0.at(index1));
for(unsigned int i=0; i<_dimension; ++i)
Expand Down Expand Up @@ -127,11 +126,9 @@ void GrossbergCalibrate::process(const std::vector< std::vector< image::Image<im

std::cout << c(i) << std::endl;

std::transform(temporaryResponse.getCurve(channel).begin(), temporaryResponse.getCurve(channel).end(), temp_hCurve.begin(), temporaryResponse.getCurve(channel).begin(), std::plus<float>());
std::transform(response.getCurve(channel).begin(), response.getCurve(channel).end(), temp_hCurve.begin(), response.getCurve(channel).begin(), std::plus<float>());
}
}
response = temporaryResponse.meanCurves();
// response = temporaryResponse;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/aliceVision/hdr/GrossbergCalibrate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace hdr {
class GrossbergCalibrate
{
public:
GrossbergCalibrate(const unsigned int dimension, const std::size_t channelQuantization = std::pow(2, 10)); // the EMOR model has 2^10 values for each curve
GrossbergCalibrate(const unsigned int dimension);


/**
Expand All @@ -28,13 +28,13 @@ class GrossbergCalibrate
* @param[out] response
*/
void process(const std::vector< std::vector< image::Image<image::RGBfColor> > > &ldrImageGroups,
const std::size_t channelQuantization,
const std::vector< std::vector<float> > &times,
const int nbPoints,
const rgbCurve &weight,
rgbCurve &response);

private:
std::size_t _channelQuantization;
unsigned int _dimension;
};

Expand Down
2 changes: 0 additions & 2 deletions src/aliceVision/hdr/hdrMerge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ void hdrMerge::process(const std::vector< image::Image<image::RGBfColor> > &imag
{
std::cout << "hdr merge" << std::endl;

weight.setGaussian(0.5, 1.0/(5.0 * sqrt(2)));

//checks
assert(!response.isEmpty());
assert(!images.empty());
Expand Down
9 changes: 9 additions & 0 deletions src/aliceVision/hdr/rgbCurve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ void rgbCurve::setGaussian(double mu, double sigma)
}
}

void rgbCurve::setRobertsonWeight()
{
for(std::size_t i = 0; i < getSize(); ++i)
{
float factor = i / (static_cast<float>(getSize() - 1)) - 0.5f;
setAllChannels(i, (std::exp( -16.f * factor * factor) - std::exp(-4.f)) / (1.f - std::exp(-4.f)));
}
}

void rgbCurve::setTriangular()
{
const float coefficient = 1.f / static_cast<float>(getSize() - 1);
Expand Down
9 changes: 7 additions & 2 deletions src/aliceVision/hdr/rgbCurve.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,13 @@ class rgbCurve
/**
*@brief Set curves to gaussian
*/
void setGaussian(double mu = 0.5, double sigma = 1.0 / (4.0 * sqrt(2.0)));
// void setGaussian(double mu = 0.5, double sigma = 1.0 / (5.0 * sqrt(2.0)));
// void setGaussian(double mu = 0.5, double sigma = 1.0 / (4.0 * sqrt(2.0)));
void setGaussian(double mu = 0.5, double sigma = 1.0 / (5.0 * sqrt(2.0)));

/**
* @brief set curve to adaptative weight for Robertson
*/
void setRobertsonWeight();

/**
*@brief Set curves to triangular
Expand Down
34 changes: 26 additions & 8 deletions src/software/convert/main_convertLDRToHDR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,14 @@ int main(int argc, char** argv)

ALICEVISION_COUT("response file: " << outputResponsePath);

const std::size_t channelQuantization = std::pow(2, 12); //RAW 12 bit precision, 2^12 values between black and white point
// set the correct calibration method corresponding to the string parameter
const ECalibrationMethod calibrationMethod = ECalibrationMethod_stringToEnum(calibrationMethodName);

std::size_t channelQuantization;
if(calibration == true && calibrationMethod == ECalibrationMethod::GROSSBERG)
channelQuantization = std::pow(2, 10);
else
channelQuantization = std::pow(2, 12); //RAW 12 bit precision, 2^12 values between black and white point
// const std::size_t channelQuantization = std::pow(2, 8); //JPG 8 bit precision, 256 values between black and white point
// const std::size_t channelQuantization = std::pow(2, 10); //RAW 10 bit precision, 2^10 values between black and white point

Expand All @@ -215,9 +222,6 @@ int main(int argc, char** argv)
// set verbose level
system::Logger::get()->setLogLevel(verboseLevel);

// set the correct calibration method corresponding to the string parameter
const ECalibrationMethod calibrationMethod = ECalibrationMethod_stringToEnum(calibrationMethodName);

// set the correct weight function corresponding to the string parameter
const hdr::EFunctionType weightFunction = hdr::EFunctionType_stringToEnum(weightFunctionName);
weight.setFunction(weightFunction);
Expand All @@ -226,7 +230,7 @@ int main(int argc, char** argv)
std::vector<std::string> inputFilesNames;
std::vector<std::string> stemImages;
std::vector<std::string> nameImages;
const std::vector<std::string> validExtensions = {".jpg", ".jpeg", ".png", ".cr2", ".tiff", ".tif"};
const std::vector<std::string> validExtensions = {".jpg", ".jpeg", ".png", ".cr2", ".tiff", ".tif", ".rw2"};
for(auto& entry: fs::directory_iterator(fs::path(imageFolder)))
{
if(fs::is_regular_file(entry.status()))
Expand All @@ -239,6 +243,16 @@ int main(int argc, char** argv)
stemImages.push_back(entry.path().stem().string());
nameImages.push_back(entry.path().filename().string());
}
else
{
ALICEVISION_LOG_ERROR("No valid image files in entry folder");
return EXIT_FAILURE;
}
}
else
{
ALICEVISION_LOG_ERROR("No regular files in entry folder");
return EXIT_FAILURE;
}
}

Expand Down Expand Up @@ -349,11 +363,13 @@ int main(int argc, char** argv)
{
case ECalibrationMethod::DEBEVEC:
{
hdr::rgbCurve wDeb(channelQuantization);
wDeb.setTriangular();
ALICEVISION_COUT("Debevec calibration");
const float lambda = channelQuantization * 1.f;
const int nbPoints = 1000;
hdr::DebevecCalibrate calibration;
calibration.process(ldrImageGroups, channelQuantization, times, nbPoints, weight, lambda, response);
calibration.process(ldrImageGroups, channelQuantization, times, nbPoints, wDeb, lambda, response);

response.exponential();
// response.scale();
Expand All @@ -362,10 +378,12 @@ int main(int argc, char** argv)

case ECalibrationMethod::ROBERTSON:
{
hdr::rgbCurve wRob(channelQuantization);
wRob.setRobertsonWeight();
ALICEVISION_COUT("Robertson calibration");
hdr::RobertsonCalibrate calibration(40);
const int nbPoints = 1000000;
calibration.process(ldrImageGroups_sorted, channelQuantization, times_sorted, nbPoints, weight, response, targetTime, threshold);
calibration.process(ldrImageGroups_sorted, channelQuantization, times_sorted, nbPoints, wRob, response, targetTime, threshold);
response.scale();
}
break;
Expand All @@ -375,7 +393,7 @@ int main(int argc, char** argv)
ALICEVISION_COUT("Grossberg calibration");
const int nbPoints = 1000000;
hdr::GrossbergCalibrate calibration(5);
calibration.process(ldrImageGroups_sorted, times_sorted, nbPoints, weight, response);
calibration.process(ldrImageGroups_sorted, channelQuantization, times_sorted, nbPoints, weight, response);
// response.scale();
}
break;
Expand Down

0 comments on commit 97455ef

Please sign in to comment.