diff --git a/modules/core/include/visp3/core/vpImage.h b/modules/core/include/visp3/core/vpImage.h index b3f82d0794..7962847d84 100644 --- a/modules/core/include/visp3/core/vpImage.h +++ b/modules/core/include/visp3/core/vpImage.h @@ -1006,8 +1006,14 @@ template double vpImage::getStdev(const vpImage *p_mask /*! * \brief Return the standard deviation of the bitmap -* -* \param[in] mean The mean of the image. + * For a vpRGBa or a vpRGBf image, we compute the standard deviation as follow: + * + * \f$ stdev = \sqrt{\frac{1}{nbValidPoints} \sum_{r = 0}^{height-1} \sum_{c = 0}^{width-1} (I[r][c].R + I[r][c].G + I[r][c].B - \mu)^2}\f$ + * + * where \f$ \mu \f$ is the mean of the image as computed by \b vpImage::getMeanValue() . + * + * \param[in] mean The mean of the image. + * \return double The standard deviation of the color image. */ template double vpImage::getStdev(const double &mean) const { @@ -1023,9 +1029,16 @@ template double vpImage::getStdev(const double &mean) const /*! * \brief Return the standard deviation of the bitmap * +* For a vpRGBa or a vpRGBf image, we compute the standard deviation as follow: +* +* \f$ stdev = \sqrt{\frac{1}{nbValidPoints} \sum_{r = 0}^{height-1} \sum_{c = 0}^{width-1} (I[r][c].R + I[r][c].G + I[r][c].B - \mu)^2 \delta(r,c)} where \delta(r,c) = 1 if p_mask[r][c], 0 otherwise\f$ +* +* where \f$ \mu \f$ is the mean of the image as computed by \b vpImage::getMeanValue() . +* * \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. +* \return double The standard deviation taking into account only the points for which the mask is true. */ template double vpImage::getStdev(const double &mean, const unsigned int &nbValidPoints, const vpImage *p_mask) const { @@ -1043,6 +1056,144 @@ template double vpImage::getStdev(const double &mean, const u return std::sqrt(sum); } +/* +/!\ Did not use Doxygen for this method because it does not handle template specialization +* Return the standard deviation of the bitmap +* +* For a vpRGBa or a vpRGBf image, we compute the standard deviation as follow: +* +* \f$ stdev = \sqrt{\frac{1}{width * height} \sum_{r = 0}^{height-1} \sum_{c = 0}^{width-1} (I[r][c].R + I[r][c].G + I[r][c].B - \mu)^2}\f$ +* +* where \f$ \mu \f$ is the mean of the image as computed by \b vpImage::getMeanValue() . +* +* param[in] mean The mean of the image. +* return The standard deviation. +*/ +template <> inline double vpImage::getStdev(const double &mean) const +{ + if ((height == 0) || (width == 0)) { + return 0.0; + } + + double res = 0.0; + const unsigned int size = height * width; + for (unsigned int i = 0; i < size; ++i) { + double val = static_cast(bitmap[i].R) + static_cast(bitmap[i].G) + static_cast(bitmap[i].B); + res += (val - mean) * (val - mean); + } + res /= static_cast(size); + return std::sqrt(res); +} + +/* +/!\ Did not use Doxygen for this method because it does not handle template specialization +* Return the standard deviation of the bitmap +* +* For a vpRGBa or a vpRGBf image, we compute the standard deviation as follow: +* +* \f$ stdev = \sqrt{\frac{1}{nbValidPoints} \sum_{r = 0}^{height-1} \sum_{c = 0}^{width-1} (I[r][c].R + I[r][c].G + I[r][c].B - \mu)^2 \delta(r,c)} where \delta(r,c) = 1 if p_mask[r][c], 0 otherwise\f$ +* +* where \f$ \mu \f$ is the mean of the image as computed by \b vpImage::getMeanValue() . +* +* 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. +* return The standard deviation taking into account only the points for which the mask is true.The standard deviation taking into account only the points for which the mask is true. +*/ +template <> inline double vpImage::getStdev(const double &mean, const unsigned int &nbValidPoints, const vpImage *p_mask) const +{ + if ((height == 0) || (width == 0)) { + return 0.0; + } + + 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]) { + double val = static_cast(bitmap[i].R) + static_cast(bitmap[i].G) + static_cast(bitmap[i].B); + sum += (val - mean) * (val - mean); + } + } + sum /= static_cast(nbValidPoints); + return std::sqrt(sum); +} + +/* +/!\ Did not use Doxygen for this method because it does not handle template specialization +* Return the standard deviation of the bitmap +* +* For a vpRGBa or a vpRGBf image, we compute the standard deviation as follow: +* +* \f$ stdev = \sqrt{\frac{1}{width * height} \sum_{r = 0}^{height-1} \sum_{c = 0}^{width-1} (I[r][c].R + I[r][c].G + I[r][c].B - \mu)^2}\f$ +* +* where \f$ \mu \f$ is the mean of the image as computed by \b vpImage::getMeanValue() . +* +* param[in] mean The mean of the image. +* return The standard deviation. +*/ +/** +* \brief \copybrief double vpImage::getStdev(const double &) const +*/ +template <> inline double vpImage::getStdev(const double &mean) const +{ + if ((height == 0) || (width == 0)) { + return 0.0; + } + + double res = 0.0; + const unsigned int size = height * width; + for (unsigned int i = 0; i < size; ++i) { + double val = static_cast(bitmap[i].R) + static_cast(bitmap[i].G) + static_cast(bitmap[i].B); + res += (val - mean) * (val - mean); + } + res /= static_cast(size); + return std::sqrt(res); +} + +/* +/!\ Did not use Doxygen for this method because it does not handle template specialization +* Return the standard deviation of the bitmap +* +* For a vpRGBa or a vpRGBf image, we compute the standard deviation as follow: +* +* \f$ stdev = \sqrt{\frac{1}{nbValidPoints} \sum_{r = 0}^{height-1} \sum_{c = 0}^{width-1} (I[r][c].R + I[r][c].G + I[r][c].B - \mu)^2 \delta(r,c)} where \delta(r,c) = 1 if p_mask[r][c], 0 otherwise\f$ +* +* where \f$ \mu \f$ is the mean of the image as computed by \b vpImage::getMeanValue() . +* +* 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. +* return The standard deviation taking into account only the points for which the mask is true. +*/ +/** +* \brief \copybrief double vpImage::getStdev(const double &, const unsigned int&, const vpImage*) const +*/ +template <> inline double vpImage::getStdev(const double &mean, const unsigned int &nbValidPoints, const vpImage *p_mask) const +{ + if ((height == 0) || (width == 0)) { + return 0.0; + } + + 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]) { + double val = static_cast(bitmap[i].R) + static_cast(bitmap[i].G) + static_cast(bitmap[i].B); + sum += (val - mean) * (val - mean); + } + } + sum /= static_cast(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. @@ -1950,7 +2101,7 @@ template <> inline vpRGBa vpImage::getValue(const vpImagePoint &ip) cons } /** - * Compute the sum of image intensities. + * \brief Compute the sum of image intensities. * For vpRGBa image type, compute the sum (R+G+B) of image intensities. */ template inline double vpImage::getSum() const @@ -1966,7 +2117,7 @@ template inline double vpImage::getSum() const } /** - * Compute the sum of image intensities. + * \brief 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. @@ -1995,6 +2146,11 @@ template inline double vpImage::getSum(const vpImage *p /** * \relates vpImage + * + * \brief Get the sum of the image. + * For a vpRGBf image, we takes the sum of the R, G and B components. + * + * \return The sum of the R, G and B components of all pixels. */ template <> inline double vpImage::getSum() const { @@ -2010,6 +2166,14 @@ template <> inline double vpImage::getSum() const /** * \relates vpImage + * \brief Get the sum of the image, taking into account the boolean mask \b p_mask + * for which a true value indicates to consider a pixel and false means to ignore it. + * For a vpRGBa image, we takes the sum of the R, G and B components. + * + * \param[in] p_mask If different from nullptr, boolean mask that tells which pixels are + * to be considered. + * \param[out] nbValidPoints The number of pixels which were taken into account. + * \return The sum of the R, G and B components of all pixels that were taken into account. */ template <> inline double vpImage::getSum(const vpImage *p_mask, unsigned int &nbValidPoints) const { @@ -2036,6 +2200,10 @@ template <> inline double vpImage::getSum(const vpImage *p_mask, u /** * \relates vpImage + * \brief Get the sum of the image. + * For a vpRGBf image, we takes the sum of the R, G and B components. + * + * \return The sum of the R, G and B components of all pixels. */ template <> inline double vpImage::getSum() const { @@ -2051,6 +2219,14 @@ template <> inline double vpImage::getSum() const /** * \relates vpImage + * \brief Get the sum of the image, taking into account the boolean mask \b p_mask + * for which a true value indicates to consider a pixel and false means to ignore it. + * For a vpRGBf image, we takes the sum of the R, G and B components. + * + * \param[in] p_mask If different from nullptr, boolean mask that tells which pixels are + * to be considered. + * \param[out] nbValidPoints The number of pixels which were taken into account. + * \return The sum of the R, G and B components of all pixels that were taken into account. */ template <> inline double vpImage::getSum(const vpImage *p_mask, unsigned int &nbValidPoints) const { diff --git a/modules/core/test/image/testImageMeanAndStdev.cpp b/modules/core/test/image/testImageMeanAndStdev.cpp new file mode 100644 index 0000000000..16176290f7 --- /dev/null +++ b/modules/core/test/image/testImageMeanAndStdev.cpp @@ -0,0 +1,906 @@ +/**************************************************************************** + * + * ViSP, open source Visual Servoing Platform software. + * Copyright (C) 2005 - 2023 by Inria. All rights reserved. + * + * This software is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * See the file LICENSE.txt at the root directory of this source + * distribution for additional information about the GNU GPL. + * + * For using ViSP with software that can not be combined with the GNU + * GPL, please contact Inria about acquiring a ViSP Professional + * Edition License. + * + * See https://visp.inria.fr for more information. + * + * This software was developed at: + * Inria Rennes - Bretagne Atlantique + * Campus Universitaire de Beaulieu + * 35042 Rennes Cedex + * France + * + * If you have questions regarding the use of this file, please contact + * Inria at visp@inria.fr + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * Description: + * Test for vpImagePoint::getValue(). + * +*****************************************************************************/ +/*! + \example testImageMeanAndStdev.cpp + + \brief Test for vpImage::getMeanValue() and vpImage::getStdev(). +*/ + +#include +#include + +void printHelp(const std::string &progName) +{ + std::cout << "SYNOPSIS: " << std::endl; + std::cout << " " << progName << " [-v, --verbose] [-h, --help]" << std::endl; + std::cout << "DETAILS:" << std::endl; + std::cout << " -v, --verbose" << std::endl; + std::cout << " Activate verbose mode to have some logs in the console." << std::endl; + std::cout << std::endl; + std::cout << " -h, --help" << std::endl; + std::cout << " Display the help about the program." << std::endl; + std::cout << std::endl; +} + +int main(const int argc, const char *argv[]) +{ + bool opt_verbose = false; + for (int i = 1; i < argc; ++i) { + std::string argName(argv[i]); + if ((argName == "-v") || (argName == "--verbose")) { + opt_verbose = true; + } + else if ((argName == "-h") || (argName == "--help")) { + printHelp(std::string(argv[0])); + return EXIT_FAILURE; + } + } + + const unsigned int nbRows = 4, nbCols = 4; + vpImage I_uchar_ref(nbRows, nbCols); + vpImage I_rgba_ref(nbRows, nbCols); + vpImage I_rgbf_ref(nbRows, nbCols); + double sum_uchar_ref = 0.; + double sum_rgba_ref = 0.; + double sum_rgbf_ref = 0.; + unsigned int count_ref = 0; + // Initialization of the images + for (unsigned int r = 0; r < nbRows; ++r) { + for (unsigned int c = 0; c < nbCols; ++c) { + unsigned int val = r * nbCols + c; + I_uchar_ref[r][c] = val; + I_rgba_ref[r][c].R = val; + I_rgba_ref[r][c].G = 2*val; + I_rgba_ref[r][c].B = 3*val; + I_rgbf_ref[r][c].R = I_rgba_ref[r][c].R; + I_rgbf_ref[r][c].G = I_rgba_ref[r][c].G; + I_rgbf_ref[r][c].B = I_rgba_ref[r][c].B; + sum_uchar_ref += static_cast(val); + double val_rgb = static_cast(I_rgba_ref[r][c].R) + static_cast(I_rgba_ref[r][c].G) + static_cast(I_rgba_ref[r][c].B); + sum_rgba_ref += val_rgb; + sum_rgbf_ref += val_rgb; + ++count_ref; + } + } + + // Computation of the means + double mean_uchar_ref = sum_uchar_ref / static_cast(count_ref); + double mean_rgba_ref = sum_rgba_ref / static_cast(count_ref); + double mean_rgbf_ref = sum_rgbf_ref / static_cast(count_ref); + + // Computation of the standard deviations + double stdev_uchar_ref = 0.; + double stdev_rgba_ref = 0.; + double stdev_rgbf_ref = 0.; + for (unsigned int r = 0; r < nbRows; ++r) { + for (unsigned int c = 0; c < nbCols; ++c) { + stdev_uchar_ref += std::pow(static_cast(I_uchar_ref[r][c]) - mean_uchar_ref, 2); + stdev_rgba_ref += std::pow(static_cast(I_rgba_ref[r][c].R) + static_cast(I_rgba_ref[r][c].G) + static_cast(I_rgba_ref[r][c].B) - mean_rgba_ref, 2); + stdev_rgbf_ref += std::pow(static_cast(I_rgbf_ref[r][c].R) + static_cast(I_rgbf_ref[r][c].G) + static_cast(I_rgbf_ref[r][c].B) - mean_rgbf_ref, 2); + } + } + stdev_uchar_ref = std::sqrt((1./static_cast(nbRows * nbCols))* stdev_uchar_ref); + stdev_rgba_ref = std::sqrt((1./static_cast(nbRows * nbCols))* stdev_rgba_ref); + stdev_rgbf_ref = std::sqrt((1./static_cast(nbRows * nbCols))* stdev_rgbf_ref); + if (opt_verbose) { + std::cout << "----- Input data-----" << std::endl; + std::cout << "I_uchar_ref = \n" << I_uchar_ref << std::endl; + std::cout << "sum_uchar_ref(I_uchar_ref) = " << sum_uchar_ref << std::endl; + std::cout << "mean_uchar_ref(I_uchar_ref) = " << mean_uchar_ref << std::endl; + std::cout << "stdev_uchar_ref(I_uchar_ref) = " << stdev_uchar_ref << std::endl; + std::cout << std::endl; + std::cout << "I_rgba_ref = \n" << I_rgba_ref << std::endl; + std::cout << "sum_rgba_ref(I_uchar_ref) = " << sum_rgba_ref << std::endl; + std::cout << "mean_rgba_ref(I_rgba_ref) = " << mean_rgba_ref << std::endl; + std::cout << "stdev_rgba_ref(I_rgba_ref) = " << stdev_rgba_ref << std::endl; + std::cout << std::endl; + std::cout << "I_rgbf_ref = \n" << I_rgbf_ref << std::endl; + std::cout << "sum_rgbf_ref(I_rgbf_ref) = " << sum_rgbf_ref << std::endl; + std::cout << "mean_rgbf_ref(I_rgbf_ref) = " << mean_rgbf_ref << std::endl; + std::cout << "stdev_rgbf_ref(I_rgbf_ref) = " << stdev_rgbf_ref << std::endl; + std::cout << std::endl; + } + + vpImage I_mask(nbRows, nbCols); + unsigned int count_true = 0; + double sum_uchar_true = 0.; + double sum_rgba_true = 0.; + double sum_rgbf_true = 0.; + for (unsigned int r = 0; r < nbRows; ++r) { + for (unsigned int c = 0; c < nbCols; ++c) { + bool isTrue = ((r + c) % 2) == 0; + I_mask[r][c] = isTrue; + if (isTrue) { + ++count_true; + sum_uchar_true += static_cast(I_uchar_ref[r][c]); + double val_rgba = static_cast(I_rgba_ref[r][c].R) + static_cast(I_rgba_ref[r][c].G) + static_cast(I_rgba_ref[r][c].B); + sum_rgba_true += val_rgba; + double val_rgbf = static_cast(I_rgbf_ref[r][c].R) + static_cast(I_rgbf_ref[r][c].G) + static_cast(I_rgbf_ref[r][c].B); + sum_rgbf_true += val_rgbf; + } + } + } + // Computation of the means when a boolean mask is used + double mean_uchar_true = sum_uchar_true / static_cast(count_true); + double mean_rgba_true = sum_rgba_true / static_cast(count_true); + double mean_rgbf_true = sum_rgbf_true / static_cast(count_true); + // Computation of the standard deviations when a boolean mask is used + double stdev_uchar_true = 0.; + double stdev_rgba_true = 0.; + double stdev_rgbf_true = 0.; + for (unsigned int r = 0; r < nbRows; ++r) { + for (unsigned int c = 0; c < nbCols; ++c) { + if (I_mask[r][c]) { + stdev_uchar_true += (static_cast(I_uchar_ref[r][c]) - mean_uchar_true) * (static_cast(I_uchar_ref[r][c]) - mean_uchar_true); + double val_rgba = static_cast(I_rgba_ref[r][c].R) + static_cast(I_rgba_ref[r][c].G) + static_cast(I_rgba_ref[r][c].B); + stdev_rgba_true += (val_rgba - mean_rgba_true) * (val_rgba - mean_rgba_true); + double val_rgbf = static_cast(I_rgbf_ref[r][c].R) + static_cast(I_rgbf_ref[r][c].G) + static_cast(I_rgbf_ref[r][c].B); + stdev_rgbf_true += (val_rgbf - mean_rgbf_true) * (val_rgbf - mean_rgbf_true); + } + } + } + stdev_uchar_true = std::sqrt((1./static_cast(count_true)) * stdev_uchar_true); + stdev_rgba_true = std::sqrt((1./static_cast(count_true)) * stdev_rgba_true); + stdev_rgbf_true = std::sqrt((1./static_cast(count_true)) * stdev_rgbf_true); + if (opt_verbose) { + std::cout << "I_mask = \n"; + for (unsigned int r = 0; r < nbRows; ++r) { + for (unsigned int c = 0; c < nbCols; ++c) { + std::cout << (I_mask[r][c] ? "true" : "false") << " "; + } + std::cout << "\n"; + } + std::cout << std::endl; + std::cout << "nb_true(I_uchar_ref, I_mask) = " << count_true << std::endl; + std::cout << "sum_uchar_true(I_uchar_ref, I_mask) = " << sum_uchar_true << std::endl; + std::cout << "mean_uchar_true(I_uchar_ref, I_mask) = " << mean_uchar_true << std::endl; + std::cout << "stdev_uchar_true(I_uchar_ref, I_mask) = " << stdev_uchar_true << std::endl; + std::cout << "sum_rgba_true(I_rgba_ref, I_mask) = " << sum_rgba_true << std::endl; + std::cout << "mean_rgba_true(I_rgba_ref, I_mask) = " << mean_rgba_true << std::endl; + std::cout << "stdev_rgba_true(I_rgba_ref, I_mask) = " << stdev_rgba_true << std::endl; + std::cout << "sum_rgbf_true(I_rgbf_ref, I_mask) = " << sum_rgbf_true << std::endl; + std::cout << "mean_rgbf_true(I_rgbf_ref, I_mask) = " << mean_rgbf_true << std::endl; + std::cout << "stdev_rgbf_true(I_rgbf_ref, I_mask) = " << stdev_rgbf_true << std::endl; + std::cout << std::endl; + } + + bool areTestOK = true; + unsigned int nbFailedTests = 0; + std::vector failedTestsNames; + if (opt_verbose) { + std::cout << "----- BEGIN tests-----" << std::endl; + } + + // Tests on the sum + { + if (opt_verbose) { + std::cout << "Tests on the sum" << std::endl; + } + std::string nameTest("vpImage::getSum()"); + double sum = I_uchar_ref.getSum(); + bool success = vpMath::equal(sum, sum_uchar_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical sum = " << sum_uchar_ref << " | returned value = " << sum << std::endl; + } + } + + unsigned int nbValidPoints = 0; + nameTest = ("vpImage::getSum( const vpImage*, unsigned int& )"); + sum = I_uchar_ref.getSum(&I_mask, nbValidPoints); + success = vpMath::equal(sum, sum_uchar_true) && (nbValidPoints == count_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << count_true << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical sum = " << sum_uchar_true << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum( const vpImage* = nullptr, unsigned int& )"); + sum = I_uchar_ref.getSum(nullptr, nbValidPoints); + success = vpMath::equal(sum, sum_uchar_ref) && (nbValidPoints == (nbCols * nbRows)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbCols * nbRows << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical sum = " << sum_uchar_ref << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum()"); + sum = I_rgba_ref.getSum(); + success = vpMath::equal(sum, sum_rgba_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical sum = " << sum_rgba_ref << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum( const vpImage*, unsigned int& )"); + sum = I_rgba_ref.getSum(&I_mask, nbValidPoints); + success = vpMath::equal(sum, sum_rgba_true) && (nbValidPoints == count_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << count_true << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical sum = " << sum_rgba_true << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum( const vpImage* = nullptr, unsigned int& )"); + sum = I_rgba_ref.getSum(nullptr, nbValidPoints); + success = vpMath::equal(sum, sum_rgba_ref) && (nbValidPoints == (nbCols * nbRows)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbCols * nbRows << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical sum = " << sum_rgba_ref << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum()"); + sum = I_rgbf_ref.getSum(); + success = vpMath::equal(sum, sum_rgbf_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical sum = " << sum_rgbf_ref << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum( const vpImage*, unsigned int& )"); + sum = I_rgbf_ref.getSum(&I_mask, nbValidPoints); + success = vpMath::equal(sum, sum_rgbf_true) && (nbValidPoints == count_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << count_true << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical sum = " << sum_rgbf_true << " | returned value = " << sum << std::endl; + } + } + + nameTest = ("vpImage::getSum( const vpImage* = nullptr, unsigned int& )"); + sum = I_rgbf_ref.getSum(nullptr, nbValidPoints); + success = vpMath::equal(sum, sum_rgbf_ref) && (nbValidPoints == (nbCols * nbRows)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbCols * nbRows << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical sum = " << sum_rgbf_ref << " | returned value = " << sum << std::endl; + } + } + } + + // Tests on the mean + { + if (opt_verbose) { + std::cout << "Tests on the mean" << std::endl; + } + std::string nameTest("vpImage::getMeanValue()"); + double mean = I_uchar_ref.getMeanValue(); + bool success = vpMath::equal(mean, mean_uchar_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_uchar_ref << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue(const vpImage*)"; + mean = I_uchar_ref.getMeanValue(&I_mask); + success = vpMath::equal(mean, mean_uchar_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_uchar_true << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue(const vpImage* = nullptr)"; + mean = I_uchar_ref.getMeanValue(nullptr); + success = vpMath::equal(mean, mean_uchar_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_uchar_ref << " | returned value = " << mean << std::endl; + } + } + + unsigned int nbValidPoints = 0; + nameTest = "vpImage::getMeanValue(const vpImage*, unsigned int &)"; + mean = I_uchar_ref.getMeanValue(&I_mask, nbValidPoints); + success = vpMath::equal(mean, mean_uchar_true) && (nbValidPoints == count_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << count_true << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical mean = " << mean_uchar_true << " | returned value = " << mean << std::endl; + } + } + + nbValidPoints = 0; + nameTest = "vpImage::getMeanValue(const vpImage* = nullptr, unsigned int &)"; + mean = I_uchar_ref.getMeanValue(nullptr, nbValidPoints); + success = vpMath::equal(mean, mean_uchar_ref) && (nbValidPoints == (nbCols * nbRows)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbCols * nbRows << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical mean = " << mean_uchar_ref << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue()"; + mean = I_rgba_ref.getMeanValue(); + success = vpMath::equal(mean, mean_rgba_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_rgba_ref << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue(const vpImage*)"; + mean = I_rgba_ref.getMeanValue(&I_mask); + success = vpMath::equal(mean, mean_rgba_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_rgba_true << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue(const vpImage* = nullptr)"; + mean = I_rgba_ref.getMeanValue(nullptr); + success = vpMath::equal(mean, mean_rgba_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_rgba_ref << " | returned value = " << mean << std::endl; + } + } + + nbValidPoints = 0; + nameTest = "vpImage::getMeanValue(const vpImage*, unsigned int &)"; + mean = I_rgba_ref.getMeanValue(&I_mask, nbValidPoints); + success = vpMath::equal(mean, mean_rgba_true) && (nbValidPoints == count_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << count_true << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical mean = " << mean_rgba_true << " | returned value = " << mean << std::endl; + } + } + + nbValidPoints = 0; + nameTest = "vpImage::getMeanValue(const vpImage* = nullptr, unsigned int &)"; + mean = I_rgba_ref.getMeanValue(nullptr, nbValidPoints); + success = vpMath::equal(mean, mean_rgba_ref) && (nbValidPoints == (nbRows * nbCols)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbRows * nbCols << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical mean = " << mean_rgba_ref << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue()"; + mean = I_rgbf_ref.getMeanValue(); + success = vpMath::equal(mean, mean_rgbf_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_rgbf_ref << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue(const vpImage*)"; + mean = I_rgbf_ref.getMeanValue(&I_mask); + success = vpMath::equal(mean, mean_rgbf_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_rgbf_true << " | returned value = " << mean << std::endl; + } + } + + nameTest = "vpImage::getMeanValue(const vpImage* = nullptr)"; + mean = I_rgbf_ref.getMeanValue(nullptr); + success = vpMath::equal(mean, mean_rgbf_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical mean = " << mean_rgbf_ref << " | returned value = " << mean << std::endl; + } + } + + nbValidPoints = 0; + nameTest = "vpImage::getMeanValue(const vpImage*, unsigned int &)"; + mean = I_rgbf_ref.getMeanValue(&I_mask, nbValidPoints); + success = vpMath::equal(mean, mean_rgbf_true) && (nbValidPoints == count_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << count_true << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical mean = " << mean_rgbf_true << " | returned value = " << mean << std::endl; + } + } + + nbValidPoints = 0; + nameTest = "vpImage::getMeanValue(const vpImage* = nullptr, unsigned int &)"; + mean = I_rgbf_ref.getMeanValue(nullptr, nbValidPoints); + success = vpMath::equal(mean, mean_rgbf_ref) && (nbValidPoints == (nbRows * nbCols)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbRows * nbCols << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical mean = " << mean_rgbf_ref << " | returned value = " << mean << std::endl; + } + } + } + + // Tests on the stdev + { + if (opt_verbose) { + std::cout << "Tests on the stdev" << std::endl; + } + std::string nameTest("vpImage::getStdev()"); + double stdev = I_uchar_ref.getStdev(); + bool success = vpMath::equal(stdev, stdev_uchar_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_uchar_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const vpImage *)"); + stdev = I_uchar_ref.getStdev(&I_mask); + success = vpMath::equal(stdev, stdev_uchar_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_uchar_true << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const vpImage * = nullptr)"); + stdev = I_uchar_ref.getStdev(nullptr); + success = vpMath::equal(stdev, stdev_uchar_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_uchar_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &)"); + double mean = I_uchar_ref.getMeanValue(); + stdev = I_uchar_ref.getStdev(mean); + success = vpMath::equal(stdev, stdev_uchar_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_uchar_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &, const unsigned int&, const vpImage*)"); + unsigned int nbValidPoints = 0; + mean = I_uchar_ref.getMeanValue(&I_mask, nbValidPoints); + stdev = I_uchar_ref.getStdev(mean, nbValidPoints, &I_mask); + success = vpMath::equal(stdev, stdev_uchar_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_uchar_true << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &, const unsigned int&, const vpImage* = nullptr)"); + nbValidPoints = 0; + mean = I_uchar_ref.getMeanValue(nullptr, nbValidPoints); + stdev = I_uchar_ref.getStdev(mean, nbValidPoints, nullptr); + success = vpMath::equal(stdev, stdev_uchar_ref) && (nbValidPoints == (nbRows * nbCols)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbRows * nbCols << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical stdev = " << stdev_uchar_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = "vpImage::getStdev()"; + stdev = I_rgba_ref.getStdev(); + success = vpMath::equal(stdev, stdev_rgba_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgba_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const vpImage *)"); + stdev = I_rgba_ref.getStdev(&I_mask); + success = vpMath::equal(stdev, stdev_rgba_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgba_true << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const vpImage * = nullptr)"); + stdev = I_rgba_ref.getStdev(nullptr); + success = vpMath::equal(stdev, stdev_rgba_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgba_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &)"); + mean = I_rgba_ref.getMeanValue(); + stdev = I_rgba_ref.getStdev(mean); + success = vpMath::equal(stdev, stdev_rgba_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgba_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &, const unsigned int&, const vpImage*)"); + nbValidPoints = 0; + mean = I_rgba_ref.getMeanValue(&I_mask, nbValidPoints); + stdev = I_rgba_ref.getStdev(mean, nbValidPoints, &I_mask); + success = vpMath::equal(stdev, stdev_rgba_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgba_true << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &, const unsigned int&, const vpImage* = nullptr)"); + nbValidPoints = 0; + mean = I_rgba_ref.getMeanValue(nullptr, nbValidPoints); + stdev = I_rgba_ref.getStdev(mean, nbValidPoints, nullptr); + success = vpMath::equal(stdev, stdev_rgba_ref) && (nbValidPoints == (nbRows * nbCols)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbRows * nbCols << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical stdev = " << stdev_rgba_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = "vpImage::getStdev()"; + stdev = I_rgbf_ref.getStdev(); + success = vpMath::equal(stdev, stdev_rgbf_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgbf_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const vpImage *)"); + stdev = I_rgbf_ref.getStdev(&I_mask); + success = vpMath::equal(stdev, stdev_rgbf_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgbf_true << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const vpImage * = nullptr)"); + stdev = I_rgbf_ref.getStdev(nullptr); + success = vpMath::equal(stdev, stdev_rgbf_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgbf_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &)"); + mean = I_rgbf_ref.getMeanValue(); + stdev = I_rgbf_ref.getStdev(mean); + success = vpMath::equal(stdev, stdev_rgbf_ref); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgbf_ref << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &, const unsigned int&, const vpImage*)"); + nbValidPoints = 0; + mean = I_rgbf_ref.getMeanValue(&I_mask, nbValidPoints); + stdev = I_rgbf_ref.getStdev(mean, nbValidPoints, &I_mask); + success = vpMath::equal(stdev, stdev_rgbf_true); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical stdev = " << stdev_rgbf_true << " | returned value = " << stdev << std::endl; + } + } + + nameTest = ("vpImage::getStdev(const double &, const unsigned int&, const vpImage* = nullptr)"); + nbValidPoints = 0; + mean = I_rgbf_ref.getMeanValue(nullptr, nbValidPoints); + stdev = I_rgbf_ref.getStdev(mean, nbValidPoints, nullptr); + success = vpMath::equal(stdev, stdev_rgbf_ref) && (nbValidPoints == (nbRows * nbCols)); + if (!success) { + ++nbFailedTests; + failedTestsNames.push_back(nameTest); + areTestOK = false; + } + if (opt_verbose) { + std::cout << "\tTest " << nameTest << ": " << (success ? "OK" : "failure") << std::endl; + if (!success) { + std::cout << "Theoretical count = " << nbRows * nbCols << " | returned value = " << nbValidPoints << std::endl; + std::cout << "Theoretical stdev = " << stdev_rgbf_ref << " | returned value = " << stdev << std::endl; + } + } + } + + if (areTestOK) { + if (opt_verbose) { + std::cout << "All tests succeeded" << std::endl; + } + return EXIT_SUCCESS; + } + else { + if (opt_verbose) { + std::cerr << nbFailedTests << " tests failed: " << std::endl; + for (unsigned int i = 0; i < nbFailedTests; ++i) { + std::cerr << " - " << failedTestsNames[i] << std::endl; + } + } + return EXIT_FAILURE; + } +}