Skip to content

Commit

Permalink
Merge pull request #825 from alicevision/dev/imageProcessingMetadata
Browse files Browse the repository at this point in the history
[software] imageProcessing: metadata feature
  • Loading branch information
fabiencastan authored Jul 19, 2020
2 parents 33d6553 + 9513e32 commit a2f6f7c
Show file tree
Hide file tree
Showing 23 changed files with 605 additions and 219 deletions.
2 changes: 1 addition & 1 deletion src/aliceVision/colorHarmonization/CommonDataByPair.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class CommonDataByPair
*/
template< typename ImageType >
static void computeHisto(
Histogram< double > & histo,
utils::Histogram< double > & histo,
const image::Image< unsigned char >& mask,
std::size_t channelIndex,
const image::Image< ImageType >& image )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class normal_distribution

BOOST_AUTO_TEST_CASE(ColorHarmonisation_Simple_offset) {

Histogram< double > histo( 0, 256, 255);
utils::Histogram< double > histo( 0, 256, 255);
for (std::size_t i=0; i < 6000; i++)
{
histo.Add(normal_distribution(127, 10)());
Expand Down Expand Up @@ -106,8 +106,8 @@ BOOST_AUTO_TEST_CASE(ColorHarmonisation_Simple_offset) {

BOOST_AUTO_TEST_CASE(ColorHarmonisation_Offset_gain) {

Histogram< double > histo_ref( 0, 256, 255);
Histogram< double > histo_offset_gain( 0, 256, 255);
utils::Histogram< double > histo_ref( 0, 256, 255);
utils::Histogram< double > histo_offset_gain( 0, 256, 255);
const double GAIN = 3.0;
const double OFFSET = 160;
//const double GAIN = 2.0;
Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/dataio/ImageFeed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ ImageFeed::FeederImpl::FeederImpl(const std::string& imagePath, const std::strin
folder = bf::path(imagePath).parent_path().string();
ALICEVISION_LOG_DEBUG("filePattern: " << filePattern);
std::string regexStr = filePattern;
re = filterToRegex(regexStr);
re = utils::filterToRegex(regexStr);
}
else
{
Expand Down
90 changes: 69 additions & 21 deletions src/aliceVision/image/convertion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,50 +13,98 @@
namespace aliceVision{
namespace image {

template<typename T>
// The factor comes from http://www.easyrgb.com/
// RGB to XYZ : Y is the luminance channel
// var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
inline T Rgb2Gray(const T r,const T g, const T b) {
return r * 0.2126 + g * 0.7152 + b * 0.0722;
inline float Rgb2GrayLinear(const float r, const float g, const float b)
{
return r * 0.2126f + g * 0.7152f + b * 0.0722f;
}

template<typename Tin, typename Tout>
inline void Convert(const Tin& valin, Tout& out) {
inline float Rgb2Gray(const float r, const float g, const float b)
{
return r * 0.299f + g * 0.587f + b * 0.114f;
}

template <typename Tin, typename Tout>
inline void Convert(const Tin& valin, Tout& out)
{
out = static_cast<Tout>(valin);
}

template<>
inline void Convert<unsigned char, RGBColor>(
const unsigned char& valin, RGBColor& valOut)
inline void Convert<unsigned char, RGBColor>(const unsigned char& valin, RGBColor& valOut)
{
valOut = RGBColor(valin);
}

template<>
inline void Convert<RGBColor, unsigned char>(
const RGBColor& valin, unsigned char& valOut)
inline void Convert<RGBColor, unsigned char>(const RGBColor& valin, unsigned char& valOut)
{
valOut = static_cast<unsigned char>(Rgb2GrayLinear(valin.r(), valin.g(), valin.b()));
}

template<>
inline void Convert<unsigned char, RGBAColor>(const unsigned char& valin, RGBAColor& valOut)
{
valOut = RGBAColor(valin, valin, valin, 255);
}

template<>
inline void Convert<RGBAColor, unsigned char>(const RGBAColor& valin, unsigned char& valOut)
{
valOut = static_cast<unsigned char>((valin.a() / 255.f) * Rgb2GrayLinear(valin.r(), valin.g(), valin.b()));
}

template<>
inline void Convert<RGBAColor, RGBColor>(const RGBAColor& valin, RGBColor& valOut)
{
valOut = RGBColor(static_cast<unsigned char>((valin.a() / 255.f) * valin.r()),
static_cast<unsigned char>((valin.a() / 255.f) * valin.g()),
static_cast<unsigned char>((valin.a() / 255.f) * valin.b()));
}

template<>
inline void Convert<RGBColor, RGBAColor>(const RGBColor& valin, RGBAColor& valOut)
{
valOut = RGBAColor(valin.r(), valin.g(), valin.b(), static_cast<unsigned char>(255));
}

template<>
inline void Convert<float, RGBfColor>(const float& valin, RGBfColor& valOut)
{
valOut = RGBfColor(valin);
}

template<>
inline void Convert<RGBfColor, float>(const RGBfColor& valin, float& valOut)
{
valOut = Rgb2GrayLinear(valin.r(), valin.g(), valin.b());
}

template<>
inline void Convert<float, RGBAfColor>(const float& valin, RGBAfColor& valOut)
{
valOut = RGBAfColor(valin);
}

template<>
inline void Convert<RGBAfColor, float>(const RGBAfColor& valin, float& valOut)
{
valOut = static_cast<unsigned char>(0.3 * valin.r() + 0.59 * valin.g() + 0.11 * valin.b());
valOut = Rgb2GrayLinear(valin.a() * valin.r(), valin.a() * valin.g(), valin.a() * valin.b());
}

template<>
inline void Convert<RGBAColor, unsigned char>(
const RGBAColor& valin, unsigned char& valOut)
inline void Convert<RGBAfColor, RGBfColor>(const RGBAfColor& valin, RGBfColor& valOut)
{
valOut = static_cast<unsigned char>(
(valin.a()/255.f) *
(0.3 * valin.r() + 0.59 * valin.g() + 0.11 * valin.b()));
valOut = RGBfColor(valin.a() * valin.r(), valin.a() * valin.g(), valin.a() * valin.b());
}

template<>
inline void Convert<RGBAColor, RGBColor>(
const RGBAColor& valin, RGBColor& valOut)
inline void Convert<RGBfColor, RGBAfColor>(const RGBfColor& valin, RGBAfColor& valOut)
{
valOut = RGBColor(
static_cast<unsigned char> ((valin.a()/255.f) * valin.r()),
static_cast<unsigned char> ((valin.a()/255.f) * valin.g()),
static_cast<unsigned char> ((valin.a()/255.f) * valin.b()));
// alpha 1 by default
valOut = RGBAfColor(valin.r(), valin.g(), valin.b());
}

template<typename ImageIn, typename ImageOut>
Expand Down
30 changes: 20 additions & 10 deletions src/aliceVision/mvsUtils/MultiViewParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <aliceVision/mvsData/imageIO.hpp>
#include <aliceVision/numeric/numeric.hpp>
#include <aliceVision/numeric/projection.hpp>
#include <aliceVision/utils/filesIO.hpp>

#include <boost/filesystem.hpp>
#include <boost/accumulators/accumulators.hpp>
Expand Down Expand Up @@ -73,17 +74,26 @@ MultiViewParams::MultiViewParams(const sfmData::SfMData& sfmData,
else if(_imagesFolder != "/" && !_imagesFolder.empty() && fs::is_directory(_imagesFolder) && !fs::is_empty(_imagesFolder))
{
// find folder file extension
const fs::recursive_directory_iterator end;
const auto findIt = std::find_if(fs::recursive_directory_iterator(_imagesFolder), end,
[&view](const fs::directory_entry& e) {
return (e.path().stem() == std::to_string(view.getViewId()) &&
(imageIO::isSupportedUndistortFormat(e.path().extension().string())));
});

if(findIt == end)
throw std::runtime_error("Cannot find image file " + std::to_string(view.getViewId()) + " in folder " + _imagesFolder);
std::vector<std::string> paths = utils::getFilesPathsFromFolder(_imagesFolder,
[&view](const fs::path& path)
{
return (path.stem() == std::to_string(view.getViewId()) && (imageIO::isSupportedUndistortFormat(path.extension().string())));
}
);

// if path was not found
if(paths.empty())
{
throw std::runtime_error("Cannot find image file coresponding to the view '" +
std::to_string(view.getViewId()) + "' in folder '" + _imagesFolder + "'.");
}
else if(paths.size() > 1)
{
throw std::runtime_error("Ambiguous case: Multiple image file found for the view '" +
std::to_string(view.getViewId()) + "' in folder '" + _imagesFolder + "'.");
}

path = _imagesFolder + std::to_string(view.getViewId()) + findIt->path().extension().string();
path = _imagesFolder + std::to_string(view.getViewId()) + fs::path(paths[0]).extension().string();
}

dimensions.emplace(view.getWidth(), view.getHeight());
Expand Down
2 changes: 1 addition & 1 deletion src/aliceVision/sfm/generateReport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ bool generateSfMReport(const sfmData::SfMData& sfmData,
htmlDocStream.pushInfo(os.str());

const double maxRange = *max_element(residuals.begin(), residuals.end());
Histogram<double> histo(0.0, maxRange, 100);
utils::Histogram<double> histo(0.0, maxRange, 100);
histo.Add(residuals.begin(), residuals.end());

svg::svgHisto svg_Histo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ void GlobalSfMRotationAveragingSolver::TripletRotationRejection(

if (!vec_errToIdentityPerTriplet.empty())
{
Histogram<float> histo(0.0f, *max_element(vec_errToIdentityPerTriplet.begin(), vec_errToIdentityPerTriplet.end()), 20);
utils::Histogram<float> histo(0.0f, *max_element(vec_errToIdentityPerTriplet.begin(), vec_errToIdentityPerTriplet.end()), 20);
histo.Add(vec_errToIdentityPerTriplet.begin(), vec_errToIdentityPerTriplet.end());
ALICEVISION_LOG_DEBUG(histo.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ void ReconstructionEngine_sequentialSfM::exportStatistics(double reconstructionT
}

// residual histogram
Histogram<double> residualHistogram;
utils::Histogram<double> residualHistogram;
{
BoxStats<double> residualStats;
computeResidualsHistogram(_sfmData, residualStats, &residualHistogram);
Expand All @@ -753,7 +753,7 @@ void ReconstructionEngine_sequentialSfM::exportStatistics(double reconstructionT
}

// tracks lengths histogram
Histogram<double> observationsLengthHistogram;
utils::Histogram<double> observationsLengthHistogram;
{
BoxStats<double> observationsLengthStats;
int overallNbObservations = 0;
Expand All @@ -765,7 +765,7 @@ void ReconstructionEngine_sequentialSfM::exportStatistics(double reconstructionT
}

// nb landmarks per view histogram
Histogram<double> landmarksPerViewHistogram;
utils::Histogram<double> landmarksPerViewHistogram;
{
BoxStats<double> landmarksPerViewStats;
computeLandmarksPerViewHistogram(_sfmData, landmarksPerViewStats, &landmarksPerViewHistogram);
Expand Down Expand Up @@ -1150,7 +1150,7 @@ bool ReconstructionEngine_sequentialSfM::makeInitialPair3D(const Pair& currentPa
}

// save outlier residual information
Histogram<double> residualHistogram;
utils::Histogram<double> residualHistogram;
BoxStats<double> residualStats;
computeResidualsHistogram(_sfmData, residualStats, &residualHistogram);
ALICEVISION_LOG_DEBUG("MSE Residual initial pair inlier: " << residualStats.mean);
Expand Down
28 changes: 14 additions & 14 deletions src/aliceVision/sfm/sfmStatistics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
namespace aliceVision {
namespace sfm {

void computeResidualsHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, Histogram<double>* out_histogram, const std::set<IndexT>& specificViews)
void computeResidualsHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, utils::Histogram<double>* out_histogram, const std::set<IndexT>& specificViews)
{
{
// Init output params
out_stats = BoxStats<double>();
if (out_histogram)
{
*out_histogram = Histogram<double>();
*out_histogram = utils::Histogram<double>();
}
}
if (sfmData.getLandmarks().empty())
Expand Down Expand Up @@ -61,20 +61,20 @@ void computeResidualsHistogram(const sfmData::SfMData& sfmData, BoxStats<double>

if (out_histogram)
{
*out_histogram = Histogram<double>(0.0, std::ceil(out_stats.max), std::ceil(out_stats.max)*2);
*out_histogram = utils::Histogram<double>(0.0, std::ceil(out_stats.max), std::ceil(out_stats.max)*2);
out_histogram->Add(vec_residuals.begin(), vec_residuals.end());
}
}


void computeObservationsLengthsHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, int& overallNbObservations, Histogram<double>* out_histogram, const std::set<IndexT>& specificViews)
void computeObservationsLengthsHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, int& overallNbObservations, utils::Histogram<double>* out_histogram, const std::set<IndexT>& specificViews)
{
{
// Init output params
out_stats = BoxStats<double>();
if (out_histogram)
{
*out_histogram = Histogram<double>();
*out_histogram = utils::Histogram<double>();
}
}
if (sfmData.getLandmarks().empty())
Expand Down Expand Up @@ -116,19 +116,19 @@ void computeObservationsLengthsHistogram(const sfmData::SfMData& sfmData, BoxSta

if (out_histogram)
{
*out_histogram = Histogram<double>(out_stats.min, out_stats.max + 1, out_stats.max - out_stats.min + 1);
*out_histogram = utils::Histogram<double>(out_stats.min, out_stats.max + 1, out_stats.max - out_stats.min + 1);
out_histogram->Add(nbObservations.begin(), nbObservations.end());
}
}

void computeLandmarksPerViewHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, Histogram<double>* out_histogram)
void computeLandmarksPerViewHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, utils::Histogram<double>* out_histogram)
{
{
// Init output params
out_stats = BoxStats<double>();
if (out_histogram)
{
*out_histogram = Histogram<double>();
*out_histogram = utils::Histogram<double>();
}
}
if(sfmData.getLandmarks().empty())
Expand Down Expand Up @@ -161,7 +161,7 @@ void computeLandmarksPerViewHistogram(const sfmData::SfMData& sfmData, BoxStats<
if (out_histogram)
{
//*out_histogram = Histogram<double>(0, sfmData.getViews().size(), sfmData.getViews().size());
*out_histogram = Histogram<double>(out_stats.min, (out_stats.max + 1), 10);
*out_histogram = utils::Histogram<double>(out_stats.min, (out_stats.max + 1), 10);
out_histogram->Add(nbLandmarksPerViewVec.begin(), nbLandmarksPerViewVec.end());
}
}
Expand Down Expand Up @@ -258,14 +258,14 @@ void computeFeatMatchPerView(const sfmData::SfMData& sfmData, std::vector<std::s
}
}

void computeScaleHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, Histogram<double>* out_histogram, const std::set<IndexT>& specificViews)
void computeScaleHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& out_stats, utils::Histogram<double>* out_histogram, const std::set<IndexT>& specificViews)
{
{
// Init output params
out_stats = BoxStats<double>();
if (out_histogram)
{
*out_histogram = Histogram<double>();
*out_histogram = utils::Histogram<double>();
}
}
if(sfmData.getLandmarks().empty())
Expand Down Expand Up @@ -297,7 +297,7 @@ void computeScaleHistogram(const sfmData::SfMData& sfmData, BoxStats<double>& ou
if (out_histogram)
{
size_t maxValue = std::ceil(out_stats.max);
*out_histogram = Histogram<double>(0.0, double(maxValue), maxValue +1);
*out_histogram = utils::Histogram<double>(0.0, double(maxValue), maxValue +1);
out_histogram->Add(vec_scaleObservations.begin(), vec_scaleObservations.end());
}
}
Expand Down Expand Up @@ -348,7 +348,7 @@ void computeResidualsPerView(const sfmData::SfMData& sfmData, int& nbViews, std:
continue;
const std::vector<double>& residuals = it->second;
BoxStats<double> residualStats(residuals.begin(), residuals.end());
Histogram<double> residual_histogram = Histogram<double>(residualStats.min, residualStats.max+1, residualStats.max - residualStats.min +1);
utils::Histogram<double> residual_histogram = utils::Histogram<double>(residualStats.min, residualStats.max+1, residualStats.max - residualStats.min +1);
residual_histogram.Add(residuals.begin(), residuals.end());

nbResidualsPerViewMin[viewIdx] = residualStats.min;
Expand Down Expand Up @@ -399,7 +399,7 @@ void computeObservationsLengthsPerView(const sfmData::SfMData& sfmData, int& nbV
const IndexT viewId = viewKeys[viewIdx];
const std::vector<int>& nbObservations = observationLengthsPerView[viewId];
BoxStats<double> observationsLengthsStats(nbObservations.begin(), nbObservations.end());
Histogram<double> observationsLengths_histogram(observationsLengthsStats.min, observationsLengthsStats.max + 1, observationsLengthsStats.max - observationsLengthsStats.min + 1);
utils::Histogram<double> observationsLengths_histogram(observationsLengthsStats.min, observationsLengthsStats.max + 1, observationsLengthsStats.max - observationsLengthsStats.min + 1);
observationsLengths_histogram.Add(nbObservations.begin(), nbObservations.end());

nbObservationsLengthsPerViewMin[viewIdx] = observationsLengthsStats.min;
Expand Down
Loading

0 comments on commit a2f6f7c

Please sign in to comment.