Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[software] imageProcessing: metadata feature #825

Merged
merged 12 commits into from
Jul 19, 2020
Merged
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