Skip to content

Commit

Permalink
Merge pull request #1346 from rolalaro/feat_gamma_auto
Browse files Browse the repository at this point in the history
Automatic Gamma correct
  • Loading branch information
fspindle authored Mar 11, 2024
2 parents 6462b34 + d66ad95 commit f04bb21
Show file tree
Hide file tree
Showing 6 changed files with 1,049 additions and 64 deletions.
7 changes: 7 additions & 0 deletions doc/tutorial/imgproc/tutorial-imgproc-brightness.dox
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ The result image is the following:

\image html img-tutorial-brighness-gamma-correction-3.5.png "Left: underexposed image - Right: image corrected with gamma=3.5"

ViSP proposes the implementation of several automatic computation of the gamma factor.
Most of these methods are designed for gray-shade images, so ViSP proposes different way
of handling the colors.

You can test the different methods using the `--gamma-method` option of the tutorial program
and the different way of handling the colors using the `--gamma-color-handling` option.

\section imgproc_brightness_histogram_equalization Histogram equalization

<a href="https://en.wikipedia.org/wiki/Histogram_equalization">Histogram equalization</a> is an image processing method that will adjust the contrast of an image by stretching or shrinking the intensity distribution in order to have a linear cumulative histogram distribution.
Expand Down
181 changes: 178 additions & 3 deletions modules/core/include/visp3/core/vpImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,13 @@ template <class Type> class vpImage
// Return the maximum value within the bitmap
Type getMaxValue(bool onlyFiniteVal = true) const;
// Return the mean value of the bitmap
Type getMeanValue() const;
double getMeanValue() const;
double getMeanValue(const vpImage<bool> *p_mask) const;
double getMeanValue(const vpImage<bool> *p_mask, unsigned int &nbValidPoints) const;
double getStdev() const;
double getStdev(const vpImage<bool> *p_mask) const;
double getStdev(const double &mean) const;
double getStdev(const double &mean, const unsigned int &nbValidPoints, const vpImage<bool> *p_mask) const;
// Return the minumum value within the bitmap
Type getMinValue(bool onlyFiniteVal = true) const;
// Look for the minumum and the maximum value within the bitmap
Expand Down Expand Up @@ -231,6 +237,7 @@ template <class Type> class vpImage

// Get image pixels sum
double getSum() const;
double getSum(const vpImage<bool> *p_mask, unsigned int &nbValidPoints) const;

/*!
Get the image width.
Expand Down Expand Up @@ -939,14 +946,103 @@ template <> inline float vpImage<float>::getMaxValue(bool onlyFiniteVal) const
/*!
\brief Return the mean value of the bitmap
*/
template <class Type> Type vpImage<Type>::getMeanValue() const
template <class Type> double vpImage<Type>::getMeanValue() const
{
if ((height == 0) || (width == 0))
if ((height == 0) || (width == 0)) {
return 0.0;
}

return getSum() / (height * width);
}

/*!
\brief Return the mean value of the bitmap
\param[in] p_mask A boolean mask that indicates which points must be considered, if set.
*/
template <class Type> double vpImage<Type>::getMeanValue(const vpImage<bool> *p_mask) const
{
unsigned int nbValidPoints = 0;
return getMeanValue(p_mask, nbValidPoints);
}

/*!
\brief Return the mean value of the bitmap
\param[in] p_mask A boolean mask that indicates which points must be considered, if set.
\param[out] nbValidPoints Number of points that are valid according to the boolean mask.
*/
template <class Type> double vpImage<Type>::getMeanValue(const vpImage<bool> *p_mask, unsigned int &nbValidPoints) const
{
nbValidPoints = 0;
if ((height == 0) || (width == 0)) {
return 0.0;
}

double sum = getSum(p_mask, nbValidPoints);
return sum / nbValidPoints;
}

/*!
* \brief Return the standard deviation of the bitmap
*/
template <class Type> double vpImage<Type>::getStdev() const
{
double mean = getMeanValue();
return getStdev(mean);
}

/*!
* \brief Return the standard deviation of the bitmap
*
* \param[in] p_mask A boolean mask that indicates which points must be considered, if set.
*/
template <class Type> double vpImage<Type>::getStdev(const vpImage<bool> *p_mask) const
{
unsigned int nbValidPoints = 0;
double mean = getMeanValue(p_mask, nbValidPoints);
return getStdev(mean, nbValidPoints, p_mask);
}

/*!
* \brief Return the standard deviation of the bitmap
*
* \param[in] mean The mean of the image.
*/
template <class Type> double vpImage<Type>::getStdev(const double &mean) const
{
const unsigned int size = width * height;
double sum = 0.;
for (unsigned int i = 0; i < size; ++i) {
sum += (bitmap[i] - mean) * (bitmap[i] - mean);
}
sum /= static_cast<double>(size);
return std::sqrt(sum);
}

/*!
* \brief Return the standard deviation of the bitmap
*
* \param[in] mean The mean of the image.
* \param[in] nbValidPoints Number of points that are valid according to the boolean mask.
* \param[in] p_mask A boolean mask that indicates which points must be considered, if set.
*/
template <class Type> double vpImage<Type>::getStdev(const double &mean, const unsigned int &nbValidPoints, const vpImage<bool> *p_mask) const
{
if (p_mask == nullptr) {
return getStdev(mean);
}
const unsigned int size = width * height;
double sum = 0.;
for (unsigned int i = 0; i < size; ++i) {
if (p_mask->bitmap[i]) {
sum += (bitmap[i] - mean) * (bitmap[i] - mean);
}
}
sum /= static_cast<double>(nbValidPoints);
return std::sqrt(sum);
}

/*!
* \brief Return the minimum value within the bitmap
* \param onlyFiniteVal : This parameter is ignored for non double or non float bitmap.
Expand Down Expand Up @@ -1869,6 +1965,34 @@ template <class Type> inline double vpImage<Type>::getSum() const
return res;
}

/**
* Compute the sum of image intensities.
* For vpRGBa image type, compute the sum (R+G+B) of image intensities.
*
* \param[in] p_mask Boolean mask that indicates the valid points by a true flag.
* \param[out] nbValidPoints The number of valid points according to the \b p_mask.
*/
template <class Type> inline double vpImage<Type>::getSum(const vpImage<bool> *p_mask, unsigned int &nbValidPoints) const
{
if ((height == 0) || (width == 0))
return 0.0;
if (p_mask == nullptr) {
nbValidPoints = height * width;
return getSum();
}

double res = 0.0;
nbValidPoints = 0;
unsigned int size = height * width;
for (unsigned int i = 0; i < size; ++i) {
if (p_mask->bitmap[i]) {
res += static_cast<double>(bitmap[i]);
++nbValidPoints;
}
}
return res;
}

/**
* \relates vpImage
*/
Expand All @@ -1884,6 +2008,32 @@ template <> inline double vpImage<vpRGBa>::getSum() const
return res;
}

/**
* \relates vpImage
*/
template <> inline double vpImage<vpRGBa>::getSum(const vpImage<bool> *p_mask, unsigned int &nbValidPoints) const
{
if ((height == 0) || (width == 0)) {
return 0.0;
}

if (p_mask == nullptr) {
nbValidPoints = height * width;
return getSum();
}

double res = 0.0;
nbValidPoints = 0;
unsigned int size = height * width;
for (unsigned int i = 0; i < size; ++i) {
if (p_mask->bitmap[i]) {
res += static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
++nbValidPoints;
}
}
return res;
}

/**
* \relates vpImage
*/
Expand All @@ -1899,6 +2049,31 @@ template <> inline double vpImage<vpRGBf>::getSum() const
return res;
}

/**
* \relates vpImage
*/
template <> inline double vpImage<vpRGBf>::getSum(const vpImage<bool> *p_mask, unsigned int &nbValidPoints) const
{
if ((height == 0) || (width == 0)) {
return 0.0;
}
if (p_mask == nullptr) {
nbValidPoints = height * width;
return getSum();
}

double res = 0.0;
nbValidPoints = 0;
unsigned int size = height * width;
for (unsigned int i = 0; i < size; ++i) {
if (p_mask->bitmap[i]) {
res += static_cast<double>(bitmap[i].R) + static_cast<double>(bitmap[i].G) + static_cast<double>(bitmap[i].B);
++nbValidPoints;
}
}
return res;
}

/*!
Operation C = *this - B.
Expand Down
Loading

0 comments on commit f04bb21

Please sign in to comment.