Skip to content

Commit

Permalink
[hdr] new ExposureSetting class
Browse files Browse the repository at this point in the history
- use double instead of float
- check if exposures are comparable: hasComparableExposures
  • Loading branch information
fabiencastan committed Apr 5, 2022
1 parent 66d6b10 commit 68ec76b
Show file tree
Hide file tree
Showing 19 changed files with 223 additions and 113 deletions.
4 changes: 2 additions & 2 deletions src/aliceVision/hdr/DebevecCalibrate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace hdr {


bool DebevecCalibrate::process(const std::vector<std::vector<ImageSample>>& ldrSamples,
const std::vector<std::vector<float>>& times, const std::size_t channelQuantization,
const std::vector<std::vector<double>>& times, const std::size_t channelQuantization,
const rgbCurve& weight, float lambda, rgbCurve& response)
{
// Always 3 channels for the input images
Expand Down Expand Up @@ -68,7 +68,7 @@ bool DebevecCalibrate::process(const std::vector<std::vector<ImageSample>>& ldrS
{
/*Process a group of brackets*/
const std::vector<ImageSample>& group = ldrSamples[groupId];
const std::vector<float> & local_times = times[groupId];
const std::vector<double> & local_times = times[groupId];

for (size_t sampleId = 0; sampleId < group.size(); sampleId++) {

Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/hdr/DebevecCalibrate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class DebevecCalibrate
* @param[out] camera response function
*/
bool process(const std::vector<std::vector<ImageSample>> & ldrSamples,
const std::vector<std::vector<float>> &times,
const std::vector<std::vector<double>> &times,
std::size_t channelQuantization,
const rgbCurve &weight,
float lambda,
Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/hdr/GrossbergCalibrate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ GrossbergCalibrate::GrossbergCalibrate(unsigned int dimension)
_dimension = dimension;
}

void GrossbergCalibrate::process(const std::vector<std::vector<ImageSample>>& ldrSamples, const std::vector<std::vector<float>>& times, std::size_t channelQuantization, rgbCurve& response)
void GrossbergCalibrate::process(const std::vector<std::vector<ImageSample>>& ldrSamples, const std::vector<std::vector<double>>& times, std::size_t channelQuantization, rgbCurve& response)
{
const double step = 1.0 / double(channelQuantization - 1);

Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/hdr/GrossbergCalibrate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class GrossbergCalibrate
* @param[out] camera response function
*/
void process(const std::vector<std::vector<ImageSample>>& ldrSamples,
const std::vector< std::vector<float> > &times,
const std::vector< std::vector<double> > &times,
std::size_t channelQuantization,
rgbCurve &response);

Expand Down
22 changes: 11 additions & 11 deletions src/aliceVision/hdr/LaguerreBACalibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,20 +159,20 @@ class ExposureConstraint : public ceres::SizedCostFunction<1, 1>
};

void LaguerreBACalibration::process(const std::vector<std::vector<ImageSample>>& ldrSamples,
std::vector<std::vector<float>>& cameraExposures,
std::vector<std::vector<double>> &cameraExposures,
const std::size_t channelQuantization,
bool refineExposures, rgbCurve& response)
{
std::map<std::pair<float, float>, double> exposureParameters;
for(std::vector<float>& group : cameraExposures)
std::map<std::pair<double, double>, double> exposureParameters;
for(std::vector<double>& group : cameraExposures)
{
for(int index = 0; index < group.size() - 1; index++)
{
std::pair<float, float> exposurePair;
std::pair<double, double> exposurePair;
exposurePair.first = group[index];
exposurePair.second = group[index + 1];
exposureParameters[exposurePair] = double(exposurePair.second) / double(exposurePair.first);
}
exposureParameters[exposurePair] = exposurePair.second / exposurePair.first;
}
}

std::array<double, 3> laguerreParam = {0.0, 0.0, 0.0};
Expand All @@ -195,7 +195,7 @@ void LaguerreBACalibration::process(const std::vector<std::vector<ImageSample>>&

for (int bracketPos = 0; bracketPos < sample.descriptions.size() - 1; bracketPos++) {

std::pair<float, float> exposurePair;
std::pair<double, double> exposurePair;
exposurePair.first = sample.descriptions[bracketPos].exposure;
exposurePair.second = sample.descriptions[bracketPos + 1].exposure;

Expand Down Expand Up @@ -258,17 +258,17 @@ void LaguerreBACalibration::process(const std::vector<std::vector<ImageSample>>&
{
for(size_t idGroup = 0; idGroup < cameraExposures.size(); idGroup++)
{
std::vector<float> & group = cameraExposures[idGroup];
std::vector<double> & group = cameraExposures[idGroup];

//Copy !
std::vector<float> res = cameraExposures[idGroup];
std::vector<double> res = cameraExposures[idGroup];

for(int index = 0; index < group.size() - 1; index++)
{
std::pair<float, float> exposurePair;
std::pair<double, double> exposurePair;
exposurePair.first = group[index];
exposurePair.second = group[index + 1];
double value = exposureParameters[exposurePair];
const double value = exposureParameters[exposurePair];
res[index + 1] = (res[res.size() - 1] * value);
}

Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/hdr/LaguerreBACalibration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class LaguerreBACalibration
*/
void process(
const std::vector<std::vector<ImageSample>>& ldrSamples,
std::vector<std::vector<float>>& cameraExposures,
std::vector<std::vector<double>>& cameraExposures,
const std::size_t channelQuantization,
bool refineExposures,
rgbCurve &response);
Expand Down
6 changes: 3 additions & 3 deletions src/aliceVision/hdr/brackets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ bool estimateBracketsFromSfmData(std::vector<std::vector<std::shared_ptr<sfmData
}

std::vector<std::shared_ptr<sfmData::View>> group;
std::vector<float> exposures;
std::vector<double> exposures;
for(auto& view : viewsOrderedByName)
{
if (countBrackets > 0)
Expand All @@ -70,7 +70,7 @@ bool estimateBracketsFromSfmData(std::vector<std::vector<std::shared_ptr<sfmData
else
{
// Automatically determines the number of brackets
float exp = view->getCameraExposureSetting();
double exp = view->getCameraExposureSetting().getExposure();
if(!exposures.empty() && exp != exposures.back() && exp == exposures.front())
{
groups.push_back(group);
Expand All @@ -94,7 +94,7 @@ bool estimateBracketsFromSfmData(std::vector<std::vector<std::shared_ptr<sfmData
[](const std::shared_ptr<sfmData::View>& a, const std::shared_ptr<sfmData::View>& b) -> bool {
if(a == nullptr || b == nullptr)
return true;
return (a->getCameraExposureSetting() < b->getCameraExposureSetting());
return (a->getCameraExposureSetting().getExposure() < b->getCameraExposureSetting().getExposure());
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/aliceVision/hdr/hdrMerge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ inline float sigmoidInv(float zeroVal, float endVal, float sigwidth, float sigMi
}

void hdrMerge::process(const std::vector< image::Image<image::RGBfColor> > &images,
const std::vector<float> &times,
const std::vector<double> &times,
const rgbCurve &weight,
const rgbCurve &response,
image::Image<image::RGBfColor> &radiance,
Expand Down Expand Up @@ -144,7 +144,7 @@ void hdrMerge::process(const std::vector< image::Image<image::RGBfColor> > &imag
}

void hdrMerge::postProcessHighlight(const std::vector< image::Image<image::RGBfColor> > &images,
const std::vector<float> &times,
const std::vector<double> &times,
const rgbCurve &weight,
const rgbCurve &response,
image::Image<image::RGBfColor> &radiance,
Expand Down
4 changes: 2 additions & 2 deletions src/aliceVision/hdr/hdrMerge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ class hdrMerge {
* @param response
*/
void process(const std::vector< image::Image<image::RGBfColor> > &images,
const std::vector<float> &times,
const std::vector<double> &times,
const rgbCurve &weight,
const rgbCurve &response,
image::Image<image::RGBfColor> &radiance,
float targetCameraExposure);

void postProcessHighlight(const std::vector< image::Image<image::RGBfColor> > &images,
const std::vector<float> &times,
const std::vector<double> &times,
const rgbCurve &weight,
const rgbCurve &response,
image::Image<image::RGBfColor> &radiance,
Expand Down
6 changes: 3 additions & 3 deletions src/aliceVision/hdr/sampling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,11 @@ void square(image::Image<image::RGBfColor> & dest, const Eigen::Matrix<image::RG
}
}

bool Sampling::extractSamplesFromImages(std::vector<ImageSample>& out_samples, const std::vector<std::string> & imagePaths, const std::vector<float>& times, const size_t imageWidth, const size_t imageHeight, const size_t channelQuantization, const EImageColorSpace & colorspace, bool applyWhiteBalance, const Sampling::Params params)
bool Sampling::extractSamplesFromImages(std::vector<ImageSample>& out_samples, const std::vector<std::string> & imagePaths, const std::vector<double>& times, const size_t imageWidth, const size_t imageHeight, const size_t channelQuantization, const EImageColorSpace & colorspace, bool applyWhiteBalance, const Sampling::Params params)
{
const int radiusp1 = params.radius + 1;
const int diameter = (params.radius * 2) + 1;
const float area = float(diameter * diameter);
const double area = double(diameter * diameter);

std::vector<std::pair<int, int>> vec_blocks;
const auto step = params.blockSize - diameter;
Expand All @@ -168,7 +168,7 @@ bool Sampling::extractSamplesFromImages(std::vector<ImageSample>& out_samples, c
image::Image<ImageSample> samples(imageWidth, imageHeight, true);
for (unsigned int idBracket = 0; idBracket < imagePaths.size(); ++idBracket)
{
const float exposure = times[idBracket];
const double exposure = times[idBracket];

image::ImageReadOptions options;
options.outputColorSpace = colorspace;
Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/hdr/sampling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class Sampling
void filter(size_t maxTotalPoints);
void extractUsefulSamples(std::vector<ImageSample> & out_samples, const std::vector<ImageSample> & samples, int imageIndex) const;

static bool extractSamplesFromImages(std::vector<ImageSample>& out_samples, const std::vector<std::string> & imagePaths, const std::vector<float>& times, const size_t imageWidth, const size_t imageHeight, const size_t channelQuantization, const image::EImageColorSpace & colorspace, bool applyWhiteBalance, const Params params);
static bool extractSamplesFromImages(std::vector<ImageSample>& out_samples, const std::vector<std::string> & imagePaths, const std::vector<double>& times, const size_t imageWidth, const size_t imageHeight, const size_t channelQuantization, const image::EImageColorSpace & colorspace, bool applyWhiteBalance, const Params params);

private:
MapSampleRefList _positions;
Expand Down
10 changes: 5 additions & 5 deletions src/aliceVision/sfmData/SfMData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,15 @@ class SfMData
* @brief Get the median Camera Exposure Setting
* @return
*/
float getMedianCameraExposureSetting() const
double getMedianCameraExposureSetting() const
{
std::vector<float> cameraExposureList;
std::vector<double> cameraExposureList;
cameraExposureList.reserve(views.size());

for(const auto& view : views)
{
float ce = view.second->getCameraExposureSetting();
if(ce != -1.0f)
const double ce = view.second->getCameraExposureSetting().getExposure();
if(ce != -1.0)
{
auto find = std::find(std::begin(cameraExposureList), std::end(cameraExposureList), ce);
if(find == std::end(cameraExposureList))
Expand All @@ -389,7 +389,7 @@ class SfMData
}

std::nth_element(cameraExposureList.begin(), cameraExposureList.begin() + cameraExposureList.size()/2, cameraExposureList.end());
float ceMedian = cameraExposureList[cameraExposureList.size()/2];
double ceMedian = cameraExposureList[cameraExposureList.size()/2];

return ceMedian;
}
Expand Down
58 changes: 2 additions & 56 deletions src/aliceVision/sfmData/View.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,63 +20,9 @@
namespace aliceVision {
namespace sfmData {

float View::getCameraExposureSetting(const float referenceISO, const float referenceFNumber) const
double View::getEv() const
{
const float shutter = getMetadataShutter();
const float fnumber = getMetadataFNumber();
if(shutter <= 0.0f || fnumber <= 0.0f)
return -1.f;

float lReferenceFNumber = referenceFNumber;
if (lReferenceFNumber <= 0.0f)
{
lReferenceFNumber = fnumber;
}

const float iso = getMetadataISO();
/*
iso = qLt / aperture^2
isoratio = iso2 / iso1 = (qLt / aperture2^2) / (qLt / aperture1^2)
isoratio = aperture1^2 / aperture2^2
aperture2^2 = aperture1^2 / isoratio
aperture2^2 = (aperture1^2 / (iso2 / iso1))
aperture2^2 = (iso1 / iso2)
aperture2 = sqrt(iso1 / iso2)
*/
float iso_2_aperture = 1.0f;
if(iso > 1e-6f && referenceISO > 1e-6f)
{
// Need to have both iso and reference iso to use it
iso_2_aperture = std::sqrt(iso / referenceISO);
}

/*
aperture = f / diameter
aperture2 / aperture1 = diameter1 / diameter2
(aperture2 / aperture1)^2 = (area1 / pi) / (area2 / pi)
area2 = (aperture1 / aperture2)^2
*/
float new_fnumber = fnumber * iso_2_aperture;
float exp_increase = (new_fnumber / lReferenceFNumber) * (new_fnumber / lReferenceFNumber);

// If the aperture was more important for this image, this means that it received less light than with a default aperture
// This means also that if we want to simulate that all the image have the same aperture, we have to increase virtually th
// light received as if the aperture was smaller. So we increase the exposure time

// If the iso is larger than the default value, this means that it recevied more light than with a default iso
// This means also that if we want to simulate that all the image have the same iso, we have to decrease virtually th
// light received as if the iso was smaller. So we decrease the exposure time or equivalent, increase the aperture value

// Checks
// iso 20, f/2 = 2500
// iso 40, f/2.8 = 2500

return shutter * exp_increase;
}

float View::getEv() const
{
return std::log2(1.f / getCameraExposureSetting());
return std::log2(1.0 / getCameraExposureSetting().getExposure());
}

std::map<std::string, std::string>::const_iterator View::findMetadataIterator(const std::string& name) const
Expand Down
Loading

0 comments on commit 68ec76b

Please sign in to comment.