/*! \ingroup group_imgproc_brightness Adjust the brightness of a grayscale image such as the new intensity is alpha x old_intensity + beta. \param I : The grayscale image to adjust the brightness. \param alpha : Multiplication coefficient. \param beta : Constant value added to the old intensity. */ void vp::adjust(vpImage<unsigned char> &I, const double alpha, const double beta) { //Construct the look-up table unsigned char lut[256]; for(unsigned int i = 0; i < 256; i++) { lut[i] = vpMath::saturate<unsigned char>(alpha * i + beta); } //Apply the transformation using a LUT I.performLut(lut); }
/*! \ingroup group_imgproc_histogram Adjust the contrast of a grayscale image by performing an histogram equalization. The intensity distribution is redistributed over the full [0 - 255] range such as the cumulative histogram distribution becomes linear. \param I : The grayscale image to apply histogram equalization. */ void vp::equalizeHistogram(vpImage<unsigned char> &I) { if(I.getWidth()*I.getHeight() == 0) { return; } //Calculate the histogram vpHistogram hist; hist.calculate(I); //Calculate the cumulative distribution function unsigned int cdf[256]; unsigned int cdfMin = /*std::numeric_limits<unsigned int>::max()*/ UINT_MAX, cdfMax = 0; unsigned int minValue = /*std::numeric_limits<unsigned int>::max()*/ UINT_MAX, maxValue = 0; cdf[0] = hist[0]; if(cdf[0] < cdfMin && cdf[0] > 0) { cdfMin = cdf[0]; minValue = 0; } for(unsigned int i = 1; i < 256; i++) { cdf[i] = cdf[i-1] + hist[i]; if(cdf[i] < cdfMin && cdf[i] > 0) { cdfMin = cdf[i]; minValue = i; } if(cdf[i] > cdfMax) { cdfMax = cdf[i]; maxValue = i; } } unsigned int nbPixels = I.getWidth()*I.getHeight(); if(nbPixels == cdfMin) { //Only one brightness value in the image return; } //Construct the look-up table unsigned char lut[256]; for(unsigned int x = minValue; x <= maxValue; x++) { lut[x] = vpMath::round( (cdf[x]-cdfMin) / (double) (nbPixels-cdfMin) * 255.0 ); } I.performLut(lut); }
/*! \ingroup group_imgproc_gamma Perform a gamma correction on a grayscale image. \param I : The grayscale image to apply gamma correction. \param gamma : Gamma value. */ void vp::gammaCorrection(vpImage<unsigned char> &I, const double gamma) { double inverse_gamma = 1.0; if(gamma > 0) { inverse_gamma = 1.0 / gamma; } else { throw vpException(vpException::badValue, "The gamma value must be positive !"); } //Construct the look-up table unsigned char lut[256]; for(unsigned int i = 0; i < 256; i++) { lut[i] = vpMath::saturate<unsigned char>( pow( (double) i / 255.0, inverse_gamma ) * 255.0 ); } I.performLut(lut); }
/*! \ingroup group_imgproc_contrast Stretch the contrast of a grayscale image. \param I : The grayscale image to stretch the contrast. */ void vp::stretchContrast(vpImage<unsigned char> &I) { //Find min and max intensity values unsigned char min = 255, max = 0; I.getMinMaxValue(min, max); unsigned char range = max - min; //Construct the look-up table unsigned char lut[256]; if(range > 0) { for(unsigned int x = min; x <= max; x++) { lut[x] = 255 * (x - min) / range; } } else { lut[min] = min; } I.performLut(lut); }
/*! \ingroup group_imgproc_contrast Stretch the contrast of a color image. \param I : The color image to stretch the contrast. */ void vp::stretchContrast(vpImage<vpRGBa> &I) { //Find min and max intensity values vpRGBa min = 255, max = 0; //Split the RGBa image into 4 images vpImage<unsigned char> pR(I.getHeight(), I.getWidth()); vpImage<unsigned char> pG(I.getHeight(), I.getWidth()); vpImage<unsigned char> pB(I.getHeight(), I.getWidth()); vpImage<unsigned char> pa(I.getHeight(), I.getWidth()); vpImageConvert::split(I, &pR, &pG, &pB, &pa); //Min max values calculated for each channel unsigned char minChannel, maxChannel; pR.getMinMaxValue(minChannel, maxChannel); min.R = minChannel; max.R = maxChannel; pG.getMinMaxValue(minChannel, maxChannel); min.G = minChannel; max.G = maxChannel; pB.getMinMaxValue(minChannel, maxChannel); min.B = minChannel; max.B = maxChannel; pa.getMinMaxValue(minChannel, maxChannel); min.A = minChannel; max.A = maxChannel; //Construct the look-up table vpRGBa lut[256]; unsigned char rangeR = max.R - min.R; if(rangeR > 0) { for(unsigned int x = min.R; x <= max.R; x++) { lut[x].R = 255 * (x - min.R) / rangeR; } } else { lut[min.R].R = min.R; } unsigned char rangeG = max.G - min.G; if(rangeG > 0) { for(unsigned int x = min.G; x <= max.G; x++) { lut[x].G = 255 * (x - min.G) / rangeG; } } else { lut[min.G].G = min.G; } unsigned char rangeB = max.B - min.B; if(rangeB > 0) { for(unsigned int x = min.B; x <= max.B; x++) { lut[x].B = 255 * (x - min.B) / rangeB; } } else { lut[min.B].B = min.B; } unsigned char rangeA = max.A - min.A; if(rangeA > 0) { for(unsigned int x = min.A; x <= max.A; x++) { lut[x].A = 255 * (x - min.A) / rangeA; } } else { lut[min.A].A = min.A; } I.performLut(lut); }