//代码可以执行,但是非常的费时间,不知为何??
#include "StdAfx.h"
#include "cv.h"
#include "highgui.h"
#include "cvaux.h"
#include "cxcore.h"
#include <iostream>
using std::cout;
using std::endl;
#include "clahe_box.h"
int roundPositive( float a );
int getPixel(CvScalar s);
int blockRadius=130;
int bins=50;
float slope=3.0;
IplImage* clahe(IplImage* img){
IplImage* img1=cvCreateImage( cvGetSize(img), img->depth, 1);
cvZero(img1);
cvNot(img1,img1);
#define max(a,b)(((a)>(b)) ? (a) : (b))
#define min(a,b)(((a)<(b)) ? (a) : (b))
/**get the message of the image(x,y,width,height)**/
clahe_box box;
box.x=0; box.y=0;
box.width=img->width; box.height=img->height;
int boxXMax=box.x+box.width;
int boxYMax=box.y+box.height;
CvScalar dst;
/**get the value of the image**/
for(int y=0; y<boxYMax; ++y){
int yMin = max( 0, y - blockRadius );
int yMax = min( img->height, y + blockRadius + 1 );
int h = yMax - yMin;
int xMin0 = max( 0, box.x - blockRadius );
int xMax0 = min( img->width - 1, box.x + blockRadius );
/* initially fill histogram */
int hist[ 255 + 1 ]={0}; //bins+1
int clippedHist[ 255 + 1 ]={0};
for ( int yi = yMin; yi < yMax; ++yi )
for ( int xi = xMin0; xi < xMax0; ++xi ){
int value=roundPositive( (getPixel(cvGet2D(img,yi,xi))) / 255.0f * bins);
//hist[value]=hist[value]+1; //the number of the same pixel value
++hist[value];
}
for ( int x = box.x; x < boxXMax; ++x )
{
int v = roundPositive( (getPixel(cvGet2D(img,y,x))) / 255.0f * bins );
int xMin = max( 0, x - blockRadius );
int xMax = x + blockRadius + 1;
int w = min( img->width, xMax ) - xMin;
int n = h * w;
int limit = ( int )( slope * n / bins + 0.5f );
/* remove left behind values from histogram */
if ( xMin > 0 )
{
int xMin1 = xMin - 1;
for ( int yi = yMin; yi < yMax; ++yi )
--hist[ roundPositive( (getPixel(cvGet2D(img,yi,xMin1))) / 255.0f * bins ) ];
}
/* add newly included values to histogram */
if ( xMax <= img->width )
{
int xMax1 = xMax - 1;
for ( int yi = yMin; yi < yMax; ++yi )
++hist[ roundPositive( (getPixel(cvGet2D(img,yi,xMax1))) / 255.0f * bins ) ];
}
/* clip histogram and redistribute clipped entries */
int length = sizeof(hist) / sizeof(int);
memcpy(clippedHist, hist, length );
int clippedEntries = 0, clippedEntriesBefore;
do
{
clippedEntriesBefore = clippedEntries;
clippedEntries = 0;
for ( int i = 0; i <= bins; ++i )
{
int d = clippedHist[ i ] - limit;
if ( d > 0 )
{
clippedEntries += d;
clippedHist[ i ] = limit;
}
}
int d = clippedEntries / ( bins + 1 );
int m = clippedEntries % ( bins + 1 );
for ( int i = 0; i <= bins; ++i)
clippedHist[ i ] += d;
if ( m != 0 )
{
int s = bins / m;
for ( int i = 0; i <= bins; i += s )
++clippedHist[ i ];
}
}
while ( clippedEntries != clippedEntriesBefore );
/////* build cdf of clipped histogram */
int hMin = bins;
for ( int i = 0; i < hMin; ++i )
if ( clippedHist[ i ] != 0 ) hMin = i;
int cdf = 0;
for ( int i = hMin; i <= v; ++i )
cdf += clippedHist[ i ];
int cdfMax = cdf;
for ( int i = v + 1; i <= bins; ++i )
cdfMax += clippedHist[ i ];
int cdfMin = clippedHist[ hMin ];
dst.val[0]=roundPositive( ( cdf - cdfMin ) / ( float )( cdfMax - cdfMin ) * 255.0f ) ;
cvSet2D(img,y,x,dst);
}
}
return img;
}
int getPixel(CvScalar s){
int pixel=(int)(s.val[0]);
return pixel;
}
int roundPositive( float a )
{
return ( int )( a + 0.5 );
}