X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=utilities%2FCxImage%2Fximahist.cpp;h=a2aed03e335614e818b15492fc871a96fa8e0b18;hb=a1ec529a24b721fcfb2c5725f95bcc2c9125b28d;hp=2b47d17d5e79eea1bb47610ac5ce84b156368a61;hpb=3fd15028ab81e6746d3af96695526d7d973a26c8;p=clitk.git diff --git a/utilities/CxImage/ximahist.cpp b/utilities/CxImage/ximahist.cpp index 2b47d17..a2aed03 100644 --- a/utilities/CxImage/ximahist.cpp +++ b/utilities/CxImage/ximahist.cpp @@ -1,627 +1,627 @@ -// xImaHist.cpp : histogram functions -/* 28/01/2004 v1.00 - www.xdp.it - * CxImage version 6.0.0 02/Feb/2008 - */ - -#include "ximage.h" - -#if CXIMAGE_SUPPORT_DSP - -//////////////////////////////////////////////////////////////////////////////// -long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace) -{ - if (!pDib) return 0; - RGBQUAD color; - - if (red) memset(red,0,256*sizeof(long)); - if (green) memset(green,0,256*sizeof(long)); - if (blue) memset(blue,0,256*sizeof(long)); - if (gray) memset(gray,0,256*sizeof(long)); - - long xmin,xmax,ymin,ymax; - if (pSelection){ - xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right; - ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top; - } else { - xmin = ymin = 0; - xmax = head.biWidth; ymax=head.biHeight; - } - - for(long y=ymin; yn) n=red[i]; - if (green && green[i]>n) n=green[i]; - if (blue && blue[i]>n) n=blue[i]; - if (gray && gray[i]>n) n=gray[i]; - } - - return n; -} -//////////////////////////////////////////////////////////////////////////////// -/** - * HistogramStretch - * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels. - * \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%); - * \return true if everything is ok - * \author [dave] and [nipper]; changes [DP] - */ -bool CxImage::HistogramStretch(long method, double threshold) -{ - if (!pDib) return false; - - double dbScaler = 50.0/head.biHeight; - long x,y; - - if ((head.biBitCount==8) && IsGrayScale()){ - - double p[256]; - memset(p, 0, 256*sizeof(double)); - for (y=0; y0 && p[maxc]<=threshold) maxc--; - - if (minc == 0 && maxc == 255) return true; - if (minc >= maxc) return true; - - // calculate LUT - BYTE lut[256]; - for (x = 0; x <256; x++){ - lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc)))); - } - - for (y=0; y - double p[256]; - memset(p, 0, 256*sizeof(double)); - for (y=0; y0 && p[maxc]<=threshold) maxc--; - - if (minc == 0 && maxc == 255) return true; - if (minc >= maxc) return true; - - // calculate LUT - BYTE lut[256]; - for (x = 0; x <256; x++){ - lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc)))); - } - - // normalize image - for (y=0; y - double pR[256]; - memset(pR, 0, 256*sizeof(double)); - double pG[256]; - memset(pG, 0, 256*sizeof(double)); - double pB[256]; - memset(pB, 0, 256*sizeof(double)); - for (y=0; y0 && pR[maxR]<=threshold2) maxR--; - - maxh = 0; - for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y]; - threshold2 = threshold*maxh; - int minG = 0; - while (minG<255 && pG[minG]<=threshold2) minG++; - int maxG = 255; - while (maxG>0 && pG[maxG]<=threshold2) maxG--; - - maxh = 0; - for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y]; - threshold2 = threshold*maxh; - int minB = 0; - while (minB<255 && pB[minB]<=threshold2) minB++; - int maxB = 255; - while (maxB>0 && pB[maxB]<=threshold2) maxB--; - - if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255) - return true; - - // calculate LUT - BYTE lutR[256]; - BYTE range = maxR - minR; - if (range != 0) { - for (x = 0; x <256; x++){ - lutR[x] = (BYTE)max(0,min(255,(255 * (x - minR) / range))); - } - } else lutR[minR] = minR; - - BYTE lutG[256]; - range = maxG - minG; - if (range != 0) { - for (x = 0; x <256; x++){ - lutG[x] = (BYTE)max(0,min(255,(255 * (x - minG) / range))); - } - } else lutG[minG] = minG; - - BYTE lutB[256]; - range = maxB - minB; - if (range != 0) { - for (x = 0; x <256; x++){ - lutB[x] = (BYTE)max(0,min(255,(255 * (x - minB) / range))); - } - } else lutB[minB] = minB; - - // normalize image - for (y=0; y - double p[256]; - memset(p, 0, 256*sizeof(double)); - for (y=0; y0 && p[maxc]<=threshold) maxc--; - - if (minc == 0 && maxc == 255) return true; - if (minc >= maxc) return true; - - // calculate LUT - BYTE lut[256]; - for (x = 0; x <256; x++){ - lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc)))); - } - - for(y=0; y : dave(at)posortho(dot)com -bool CxImage::HistogramEqualize() -{ - if (!pDib) return false; - - int histogram[256]; - int map[256]; - int equalize_map[256]; - int x, y, i, j; - RGBQUAD color; - RGBQUAD yuvClr; - unsigned int YVal, high, low; - - memset( &histogram, 0, sizeof(int) * 256 ); - memset( &map, 0, sizeof(int) * 256 ); - memset( &equalize_map, 0, sizeof(int) * 256 ); - - // form histogram - for(y=0; y < head.biHeight; y++){ - info.nProgress = (long)(50*y/head.biHeight); - if (info.nEscape) break; - for(x=0; x < head.biWidth; x++){ - color = BlindGetPixelColor( x, y ); - YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); - histogram[YVal]++; - } - } - - // integrate the histogram to get the equalization map. - j = 0; - for(i=0; i <= 255; i++){ - j += histogram[i]; - map[i] = j; - } - - // equalize - low = map[0]; - high = map[255]; - if (low == high) return false; - for( i = 0; i <= 255; i++ ){ - equalize_map[i] = (unsigned int)((((double)( map[i] - low ) ) * 255) / ( high - low ) ); - } - - // stretch the histogram - if(head.biClrUsed == 0){ // No Palette - for( y = 0; y < head.biHeight; y++ ){ - info.nProgress = (long)(50+50*y/head.biHeight); - if (info.nEscape) break; - for( x = 0; x < head.biWidth; x++ ){ - - color = BlindGetPixelColor( x, y ); - yuvClr = RGBtoYUV(color); - - yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed]; - - color = YUVtoRGB(yuvClr); - BlindSetPixelColor( x, y, color ); - } - } - } else { // Palette - for( i = 0; i < (int)head.biClrUsed; i++ ){ - - color = GetPaletteColor((BYTE)i); - yuvClr = RGBtoYUV(color); - - yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed]; - - color = YUVtoRGB(yuvClr); - SetPaletteColor( (BYTE)i, color ); - } - } - return true; -} -//////////////////////////////////////////////////////////////////////////////// -// HistogramNormalize function by : dave(at)posortho(dot)com -bool CxImage::HistogramNormalize() -{ - if (!pDib) return false; - - int histogram[256]; - int threshold_intensity, intense; - int x, y, i; - unsigned int normalize_map[256]; - unsigned int high, low, YVal; - - RGBQUAD color; - RGBQUAD yuvClr; - - memset( &histogram, 0, sizeof( int ) * 256 ); - memset( &normalize_map, 0, sizeof( unsigned int ) * 256 ); - - // form histogram - for(y=0; y < head.biHeight; y++){ - info.nProgress = (long)(50*y/head.biHeight); - if (info.nEscape) break; - for(x=0; x < head.biWidth; x++){ - color = BlindGetPixelColor( x, y ); - YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); - histogram[YVal]++; - } - } - - // find histogram boundaries by locating the 1 percent levels - threshold_intensity = ( head.biWidth * head.biHeight) / 100; - - intense = 0; - for( low = 0; low < 255; low++ ){ - intense += histogram[low]; - if( intense > threshold_intensity ) break; - } - - intense = 0; - for( high = 255; high != 0; high--){ - intense += histogram[ high ]; - if( intense > threshold_intensity ) break; - } - - if ( low == high ){ - // Unreasonable contrast; use zero threshold to determine boundaries. - threshold_intensity = 0; - intense = 0; - for( low = 0; low < 255; low++){ - intense += histogram[low]; - if( intense > threshold_intensity ) break; - } - intense = 0; - for( high = 255; high != 0; high-- ){ - intense += histogram [high ]; - if( intense > threshold_intensity ) break; - } - } - if( low == high ) return false; // zero span bound - - // Stretch the histogram to create the normalized image mapping. - for(i = 0; i <= 255; i++){ - if ( i < (int) low ){ - normalize_map[i] = 0; - } else { - if(i > (int) high) - normalize_map[i] = 255; - else - normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low ); - } - } - - // Normalize - if( head.biClrUsed == 0 ){ - for( y = 0; y < head.biHeight; y++ ){ - info.nProgress = (long)(50+50*y/head.biHeight); - if (info.nEscape) break; - for( x = 0; x < head.biWidth; x++ ){ - - color = BlindGetPixelColor( x, y ); - yuvClr = RGBtoYUV( color ); - - yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed]; - - color = YUVtoRGB( yuvClr ); - BlindSetPixelColor( x, y, color ); - } - } - } else { - for(i = 0; i < (int)head.biClrUsed; i++){ - - color = GetPaletteColor( (BYTE)i ); - yuvClr = RGBtoYUV( color ); - - yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed]; - - color = YUVtoRGB( yuvClr ); - SetPaletteColor( (BYTE)i, color ); - } - } - return true; -} -//////////////////////////////////////////////////////////////////////////////// -// HistogramLog function by : dave(at)posortho(dot)com -bool CxImage::HistogramLog() -{ - if (!pDib) return false; - - //q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|); - int x, y, i; - RGBQUAD color; - RGBQUAD yuvClr; - - unsigned int YVal, high = 1; - - // Find Highest Luminance Value in the Image - if( head.biClrUsed == 0 ){ // No Palette - for(y=0; y < head.biHeight; y++){ - info.nProgress = (long)(50*y/head.biHeight); - if (info.nEscape) break; - for(x=0; x < head.biWidth; x++){ - color = BlindGetPixelColor( x, y ); - YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); - if (YVal > high ) high = YVal; - } - } - } else { // Palette - for(i = 0; i < (int)head.biClrUsed; i++){ - color = GetPaletteColor((BYTE)i); - YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); - if (YVal > high ) high = YVal; - } - } - - // Logarithm Operator - double k = 255.0 / ::log( 1.0 + (double)high ); - if( head.biClrUsed == 0 ){ - for( y = 0; y < head.biHeight; y++ ){ - info.nProgress = (long)(50+50*y/head.biHeight); - if (info.nEscape) break; - for( x = 0; x < head.biWidth; x++ ){ - - color = BlindGetPixelColor( x, y ); - yuvClr = RGBtoYUV( color ); - - yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) ); - - color = YUVtoRGB( yuvClr ); - BlindSetPixelColor( x, y, color ); - } - } - } else { - for(i = 0; i < (int)head.biClrUsed; i++){ - - color = GetPaletteColor( (BYTE)i ); - yuvClr = RGBtoYUV( color ); - - yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) ); - - color = YUVtoRGB( yuvClr ); - SetPaletteColor( (BYTE)i, color ); - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// HistogramRoot function by : dave(at)posortho(dot)com -bool CxImage::HistogramRoot() -{ - if (!pDib) return false; - //q(i,j) = sqrt(|p(i,j)|); - - int x, y, i; - RGBQUAD color; - RGBQUAD yuvClr; - double dtmp; - unsigned int YVal, high = 1; - - // Find Highest Luminance Value in the Image - if( head.biClrUsed == 0 ){ // No Palette - for(y=0; y < head.biHeight; y++){ - info.nProgress = (long)(50*y/head.biHeight); - if (info.nEscape) break; - for(x=0; x < head.biWidth; x++){ - color = BlindGetPixelColor( x, y ); - YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); - if (YVal > high ) high = YVal; - } - } - } else { // Palette - for(i = 0; i < (int)head.biClrUsed; i++){ - color = GetPaletteColor((BYTE)i); - YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); - if (YVal > high ) high = YVal; - } - } - - // Root Operator - double k = 128.0 / ::log( 1.0 + (double)high ); - if( head.biClrUsed == 0 ){ - for( y = 0; y < head.biHeight; y++ ){ - info.nProgress = (long)(50+50*y/head.biHeight); - if (info.nEscape) break; - for( x = 0; x < head.biWidth; x++ ){ - - color = BlindGetPixelColor( x, y ); - yuvClr = RGBtoYUV( color ); - - dtmp = k * ::sqrt( (double)yuvClr.rgbRed ); - if ( dtmp > 255.0 ) dtmp = 255.0; - if ( dtmp < 0 ) dtmp = 0; - yuvClr.rgbRed = (BYTE)dtmp; - - color = YUVtoRGB( yuvClr ); - BlindSetPixelColor( x, y, color ); - } - } - } else { - for(i = 0; i < (int)head.biClrUsed; i++){ - - color = GetPaletteColor( (BYTE)i ); - yuvClr = RGBtoYUV( color ); - - dtmp = k * ::sqrt( (double)yuvClr.rgbRed ); - if ( dtmp > 255.0 ) dtmp = 255.0; - if ( dtmp < 0 ) dtmp = 0; - yuvClr.rgbRed = (BYTE)dtmp; - - color = YUVtoRGB( yuvClr ); - SetPaletteColor( (BYTE)i, color ); - } - } - - return true; -} -//////////////////////////////////////////////////////////////////////////////// -#endif +// xImaHist.cpp : histogram functions +/* 28/01/2004 v1.00 - www.xdp.it + * CxImage version 6.0.0 02/Feb/2008 + */ + +#include "ximage.h" + +#if CXIMAGE_SUPPORT_DSP + +//////////////////////////////////////////////////////////////////////////////// +long CxImage::Histogram(long* red, long* green, long* blue, long* gray, long colorspace) +{ + if (!pDib) return 0; + RGBQUAD color; + + if (red) memset(red,0,256*sizeof(long)); + if (green) memset(green,0,256*sizeof(long)); + if (blue) memset(blue,0,256*sizeof(long)); + if (gray) memset(gray,0,256*sizeof(long)); + + long xmin,xmax,ymin,ymax; + if (pSelection){ + xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right; + ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top; + } else { + xmin = ymin = 0; + xmax = head.biWidth; ymax=head.biHeight; + } + + for(long y=ymin; yn) n=red[i]; + if (green && green[i]>n) n=green[i]; + if (blue && blue[i]>n) n=blue[i]; + if (gray && gray[i]>n) n=gray[i]; + } + + return n; +} +//////////////////////////////////////////////////////////////////////////////// +/** + * HistogramStretch + * \param method: 0 = luminance (default), 1 = linked channels , 2 = independent channels. + * \param threshold: minimum percentage level in the histogram to recognize it as meaningful. Range: 0.0 to 1.0; default = 0; typical = 0.005 (0.5%); + * \return true if everything is ok + * \author [dave] and [nipper]; changes [DP] + */ +bool CxImage::HistogramStretch(long method, double threshold) +{ + if (!pDib) return false; + + double dbScaler = 50.0/head.biHeight; + long x,y; + + if ((head.biBitCount==8) && IsGrayScale()){ + + double p[256]; + memset(p, 0, 256*sizeof(double)); + for (y=0; y0 && p[maxc]<=threshold) maxc--; + + if (minc == 0 && maxc == 255) return true; + if (minc >= maxc) return true; + + // calculate LUT + BYTE lut[256]; + for (x = 0; x <256; x++){ + lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc)))); + } + + for (y=0; y + double p[256]; + memset(p, 0, 256*sizeof(double)); + for (y=0; y0 && p[maxc]<=threshold) maxc--; + + if (minc == 0 && maxc == 255) return true; + if (minc >= maxc) return true; + + // calculate LUT + BYTE lut[256]; + for (x = 0; x <256; x++){ + lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc)))); + } + + // normalize image + for (y=0; y + double pR[256]; + memset(pR, 0, 256*sizeof(double)); + double pG[256]; + memset(pG, 0, 256*sizeof(double)); + double pB[256]; + memset(pB, 0, 256*sizeof(double)); + for (y=0; y0 && pR[maxR]<=threshold2) maxR--; + + maxh = 0; + for (y=0; y<255; y++) if (maxh < pG[y]) maxh = pG[y]; + threshold2 = threshold*maxh; + int minG = 0; + while (minG<255 && pG[minG]<=threshold2) minG++; + int maxG = 255; + while (maxG>0 && pG[maxG]<=threshold2) maxG--; + + maxh = 0; + for (y=0; y<255; y++) if (maxh < pB[y]) maxh = pB[y]; + threshold2 = threshold*maxh; + int minB = 0; + while (minB<255 && pB[minB]<=threshold2) minB++; + int maxB = 255; + while (maxB>0 && pB[maxB]<=threshold2) maxB--; + + if (minR == 0 && maxR == 255 && minG == 0 && maxG == 255 && minB == 0 && maxB == 255) + return true; + + // calculate LUT + BYTE lutR[256]; + BYTE range = maxR - minR; + if (range != 0) { + for (x = 0; x <256; x++){ + lutR[x] = (BYTE)max(0,min(255,(255 * (x - minR) / range))); + } + } else lutR[minR] = minR; + + BYTE lutG[256]; + range = maxG - minG; + if (range != 0) { + for (x = 0; x <256; x++){ + lutG[x] = (BYTE)max(0,min(255,(255 * (x - minG) / range))); + } + } else lutG[minG] = minG; + + BYTE lutB[256]; + range = maxB - minB; + if (range != 0) { + for (x = 0; x <256; x++){ + lutB[x] = (BYTE)max(0,min(255,(255 * (x - minB) / range))); + } + } else lutB[minB] = minB; + + // normalize image + for (y=0; y + double p[256]; + memset(p, 0, 256*sizeof(double)); + for (y=0; y0 && p[maxc]<=threshold) maxc--; + + if (minc == 0 && maxc == 255) return true; + if (minc >= maxc) return true; + + // calculate LUT + BYTE lut[256]; + for (x = 0; x <256; x++){ + lut[x] = (BYTE)max(0,min(255,(255 * (x - minc) / (maxc - minc)))); + } + + for(y=0; y : dave(at)posortho(dot)com +bool CxImage::HistogramEqualize() +{ + if (!pDib) return false; + + int histogram[256]; + int map[256]; + int equalize_map[256]; + int x, y, i, j; + RGBQUAD color; + RGBQUAD yuvClr; + unsigned int YVal, high, low; + + memset( &histogram, 0, sizeof(int) * 256 ); + memset( &map, 0, sizeof(int) * 256 ); + memset( &equalize_map, 0, sizeof(int) * 256 ); + + // form histogram + for(y=0; y < head.biHeight; y++){ + info.nProgress = (long)(50*y/head.biHeight); + if (info.nEscape) break; + for(x=0; x < head.biWidth; x++){ + color = BlindGetPixelColor( x, y ); + YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); + histogram[YVal]++; + } + } + + // integrate the histogram to get the equalization map. + j = 0; + for(i=0; i <= 255; i++){ + j += histogram[i]; + map[i] = j; + } + + // equalize + low = map[0]; + high = map[255]; + if (low == high) return false; + for( i = 0; i <= 255; i++ ){ + equalize_map[i] = (unsigned int)((((double)( map[i] - low ) ) * 255) / ( high - low ) ); + } + + // stretch the histogram + if(head.biClrUsed == 0){ // No Palette + for( y = 0; y < head.biHeight; y++ ){ + info.nProgress = (long)(50+50*y/head.biHeight); + if (info.nEscape) break; + for( x = 0; x < head.biWidth; x++ ){ + + color = BlindGetPixelColor( x, y ); + yuvClr = RGBtoYUV(color); + + yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed]; + + color = YUVtoRGB(yuvClr); + BlindSetPixelColor( x, y, color ); + } + } + } else { // Palette + for( i = 0; i < (int)head.biClrUsed; i++ ){ + + color = GetPaletteColor((BYTE)i); + yuvClr = RGBtoYUV(color); + + yuvClr.rgbRed = (BYTE)equalize_map[yuvClr.rgbRed]; + + color = YUVtoRGB(yuvClr); + SetPaletteColor( (BYTE)i, color ); + } + } + return true; +} +//////////////////////////////////////////////////////////////////////////////// +// HistogramNormalize function by : dave(at)posortho(dot)com +bool CxImage::HistogramNormalize() +{ + if (!pDib) return false; + + int histogram[256]; + int threshold_intensity, intense; + int x, y, i; + unsigned int normalize_map[256]; + unsigned int high, low, YVal; + + RGBQUAD color; + RGBQUAD yuvClr; + + memset( &histogram, 0, sizeof( int ) * 256 ); + memset( &normalize_map, 0, sizeof( unsigned int ) * 256 ); + + // form histogram + for(y=0; y < head.biHeight; y++){ + info.nProgress = (long)(50*y/head.biHeight); + if (info.nEscape) break; + for(x=0; x < head.biWidth; x++){ + color = BlindGetPixelColor( x, y ); + YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); + histogram[YVal]++; + } + } + + // find histogram boundaries by locating the 1 percent levels + threshold_intensity = ( head.biWidth * head.biHeight) / 100; + + intense = 0; + for( low = 0; low < 255; low++ ){ + intense += histogram[low]; + if( intense > threshold_intensity ) break; + } + + intense = 0; + for( high = 255; high != 0; high--){ + intense += histogram[ high ]; + if( intense > threshold_intensity ) break; + } + + if ( low == high ){ + // Unreasonable contrast; use zero threshold to determine boundaries. + threshold_intensity = 0; + intense = 0; + for( low = 0; low < 255; low++){ + intense += histogram[low]; + if( intense > threshold_intensity ) break; + } + intense = 0; + for( high = 255; high != 0; high-- ){ + intense += histogram [high ]; + if( intense > threshold_intensity ) break; + } + } + if( low == high ) return false; // zero span bound + + // Stretch the histogram to create the normalized image mapping. + for(i = 0; i <= 255; i++){ + if ( i < (int) low ){ + normalize_map[i] = 0; + } else { + if(i > (int) high) + normalize_map[i] = 255; + else + normalize_map[i] = ( 255 - 1) * ( i - low) / ( high - low ); + } + } + + // Normalize + if( head.biClrUsed == 0 ){ + for( y = 0; y < head.biHeight; y++ ){ + info.nProgress = (long)(50+50*y/head.biHeight); + if (info.nEscape) break; + for( x = 0; x < head.biWidth; x++ ){ + + color = BlindGetPixelColor( x, y ); + yuvClr = RGBtoYUV( color ); + + yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed]; + + color = YUVtoRGB( yuvClr ); + BlindSetPixelColor( x, y, color ); + } + } + } else { + for(i = 0; i < (int)head.biClrUsed; i++){ + + color = GetPaletteColor( (BYTE)i ); + yuvClr = RGBtoYUV( color ); + + yuvClr.rgbRed = (BYTE)normalize_map[yuvClr.rgbRed]; + + color = YUVtoRGB( yuvClr ); + SetPaletteColor( (BYTE)i, color ); + } + } + return true; +} +//////////////////////////////////////////////////////////////////////////////// +// HistogramLog function by : dave(at)posortho(dot)com +bool CxImage::HistogramLog() +{ + if (!pDib) return false; + + //q(i,j) = 255/log(1 + |high|) * log(1 + |p(i,j)|); + int x, y, i; + RGBQUAD color; + RGBQUAD yuvClr; + + unsigned int YVal, high = 1; + + // Find Highest Luminance Value in the Image + if( head.biClrUsed == 0 ){ // No Palette + for(y=0; y < head.biHeight; y++){ + info.nProgress = (long)(50*y/head.biHeight); + if (info.nEscape) break; + for(x=0; x < head.biWidth; x++){ + color = BlindGetPixelColor( x, y ); + YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); + if (YVal > high ) high = YVal; + } + } + } else { // Palette + for(i = 0; i < (int)head.biClrUsed; i++){ + color = GetPaletteColor((BYTE)i); + YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); + if (YVal > high ) high = YVal; + } + } + + // Logarithm Operator + double k = 255.0 / ::log( 1.0 + (double)high ); + if( head.biClrUsed == 0 ){ + for( y = 0; y < head.biHeight; y++ ){ + info.nProgress = (long)(50+50*y/head.biHeight); + if (info.nEscape) break; + for( x = 0; x < head.biWidth; x++ ){ + + color = BlindGetPixelColor( x, y ); + yuvClr = RGBtoYUV( color ); + + yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) ); + + color = YUVtoRGB( yuvClr ); + BlindSetPixelColor( x, y, color ); + } + } + } else { + for(i = 0; i < (int)head.biClrUsed; i++){ + + color = GetPaletteColor( (BYTE)i ); + yuvClr = RGBtoYUV( color ); + + yuvClr.rgbRed = (BYTE)(k * ::log( 1.0 + (double)yuvClr.rgbRed ) ); + + color = YUVtoRGB( yuvClr ); + SetPaletteColor( (BYTE)i, color ); + } + } + + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +// HistogramRoot function by : dave(at)posortho(dot)com +bool CxImage::HistogramRoot() +{ + if (!pDib) return false; + //q(i,j) = sqrt(|p(i,j)|); + + int x, y, i; + RGBQUAD color; + RGBQUAD yuvClr; + double dtmp; + unsigned int YVal, high = 1; + + // Find Highest Luminance Value in the Image + if( head.biClrUsed == 0 ){ // No Palette + for(y=0; y < head.biHeight; y++){ + info.nProgress = (long)(50*y/head.biHeight); + if (info.nEscape) break; + for(x=0; x < head.biWidth; x++){ + color = BlindGetPixelColor( x, y ); + YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); + if (YVal > high ) high = YVal; + } + } + } else { // Palette + for(i = 0; i < (int)head.biClrUsed; i++){ + color = GetPaletteColor((BYTE)i); + YVal = (unsigned int)RGB2GRAY(color.rgbRed, color.rgbGreen, color.rgbBlue); + if (YVal > high ) high = YVal; + } + } + + // Root Operator + double k = 128.0 / ::log( 1.0 + (double)high ); + if( head.biClrUsed == 0 ){ + for( y = 0; y < head.biHeight; y++ ){ + info.nProgress = (long)(50+50*y/head.biHeight); + if (info.nEscape) break; + for( x = 0; x < head.biWidth; x++ ){ + + color = BlindGetPixelColor( x, y ); + yuvClr = RGBtoYUV( color ); + + dtmp = k * ::sqrt( (double)yuvClr.rgbRed ); + if ( dtmp > 255.0 ) dtmp = 255.0; + if ( dtmp < 0 ) dtmp = 0; + yuvClr.rgbRed = (BYTE)dtmp; + + color = YUVtoRGB( yuvClr ); + BlindSetPixelColor( x, y, color ); + } + } + } else { + for(i = 0; i < (int)head.biClrUsed; i++){ + + color = GetPaletteColor( (BYTE)i ); + yuvClr = RGBtoYUV( color ); + + dtmp = k * ::sqrt( (double)yuvClr.rgbRed ); + if ( dtmp > 255.0 ) dtmp = 255.0; + if ( dtmp < 0 ) dtmp = 0; + yuvClr.rgbRed = (BYTE)dtmp; + + color = YUVtoRGB( yuvClr ); + SetPaletteColor( (BYTE)i, color ); + } + } + + return true; +} +//////////////////////////////////////////////////////////////////////////////// +#endif