为了提高运行速度,把CLAHE的代码进行了修改,方便运行。
CLAHE.h
class CLAHE { public: CLAHE(void); ~CLAHE(void); int m_nGridX; /* CLAHE 宽网格的个数 */ int m_nGridY; /* CLAHE 高网格的个数 */ unsigned char m_aLUT[256]; /* CLAHE lookup table used for scaling of input image */ int Initial(int nMaxPixel, int nMinPixel, int uiNrBins, int nX, int nY, int nWidth, int nHeight,float fCliplimit); int m_nWidth; int m_nHeight; int m_nCliplimit; int m_nHistBins; int m_nGridSize_X; int m_nGridSize_Y; int *m_pMapArray; int m_nGridSize; /* Actual size of contextual regions */ int ProcessCLAHE(unsigned char* pImage); void MakeHistogram(unsigned char* pImage,int* pulHistogram); void ClipHistogram(int* pulHistogram); void MapHistogram(int* pulHistogram); void Interpolate (unsigned char * pImage); int m_nMaxPixel; int m_nMinPixel; void ShiftInterpolate(unsigned char* pImage, int nSizeX, int nSizeY, int* pulMapLU, int* pulMapRU, int *pulMapLB, int *pulMapRB); int LineInterpolate(unsigned char* pImage, int nSizeX, int nSizeY, int* pLU, int* pRU, int* pLB, int* pRB); };
CLAH.CPP
const unsigned int uiMAX_REG_X = 16; /* max. # contextual regions in x-direction */ const unsigned int uiMAX_REG_Y = 16; /* max. # contextual regions in y-direction */ #define uiNR_OF_GREY (256) #define uiNR_OF_GREY (4096) CLAHE::CLAHE(void) : m_nGridX(0) , m_nGridY(0) , m_nWidth(0) , m_nHeight(0) , m_nCliplimit(0) , m_nHistBins(0) , m_nGridSize_X(0) , m_nGridSize_Y(0) , m_pMapArray(0) , m_nGridSize(0) , m_nMaxPixel(0) , m_nMinPixel(0) { } CLAHE::~CLAHE(void) { } int CLAHE::Initial(int nMaxPixel, int nMinPixel, int uiNrBins, int nX, int nY, int nWidth, int nHeight, float fCliplimit) { if (nX > uiMAX_REG_X) return -1; /* # of regions x-direction too large */ if (nY > uiMAX_REG_Y) return -2; /* # of regions y-direction too large */ if (nWidth % nX) return -3; /* x-resolution no multiple of uiNrX */ if (nHeight % nY) return -4; /* y-resolution no multiple of uiNrY */ if (nMaxPixel >= uiNR_OF_GREY) return -5; /* maximum too large */ if (nMinPixel >= nMaxPixel) return -6; /* minimum equal or larger than maximum */ if (nX < 2 || nY < 2) return -7; /* at least 4 contextual regions required */ if (fCliplimit == 1.0) return 0; /* is OK, immediately returns original image. */ if (uiNrBins == 0) uiNrBins = 128; /* default value when not specified */ /* Make lookup table for mapping of greyvalues */ int i; const unsigned char BinSize = (unsigned char)(1 + (nMaxPixel-nMinPixel)/uiNrBins); for (i=nMinPixel; i<=nMaxPixel; i++) m_aLUT[i] = (i-nMinPixel) / BinSize; m_nMinPixel = nMinPixel; m_nMaxPixel = nMaxPixel; m_nGridX = nX; m_nGridY = nY; m_nWidth = nWidth; m_nHeight = nHeight; m_nHistBins = uiNrBins; m_nGridSize_X = m_nWidth / m_nGridX; m_nGridSize_Y = m_nHeight / m_nGridY; m_nGridSize = m_nGridSize_X * m_nGridSize_Y; if(fCliplimit > 0.0) { /* Calculate actual cliplimit */ m_nCliplimit = fCliplimit * m_nGridSize / uiNrBins; m_nCliplimit = (m_nCliplimit < 1) ? 1: m_nCliplimit; } m_pMapArray=(int *)malloc(sizeof(int)*m_nGridX*m_nGridY*m_nHistBins); if (m_pMapArray == 0) return -8; /* Not enough memory! (try reducing uiNrBins) */ return 1; } int CLAHE::ProcessCLAHE(unsigned char* pImage) { int x,y; unsigned char* pImPointer; int *pulHist; int uiSubX, uiSubY; int uiXL, uiXR, uiYU, uiYB; /* auxiliary variables interpolation routine */ int * pulLU, *pulLB, *pulRU, *pulRB; /* auxiliary pointers interpolation */ /* Calculate greylevel mappings for each contextual region */ for (y=0,pImPointer=pImage; y0) ulNrExcess += lBinExcess; /* excess in current bin */ } /* Second part: clip histogram and redistribute excess pixels in each bin */ ulBinIncr = ulNrExcess / m_nHistBins; /* average binincrement */ ulUpper = m_nCliplimit - ulBinIncr; /* Bins larger than ulUpper set to cliplimit */ for (i=0; i m_nCliplimit) pulHistogram[i] = m_nCliplimit; /* clip bin */ else { if (pulHistogram[i] > ulUpper) { /* high bin count */ ulNrExcess -= (pulHistogram[i] - ulUpper); pulHistogram[i]= m_nCliplimit; } else { /* low bin count */ ulNrExcess -= ulBinIncr; pulHistogram[i] += ulBinIncr; } } } while (ulNrExcess) { /* Redistribute remaining excess */ pulEndPointer = &pulHistogram[m_nHistBins]; pulHisto = pulHistogram; while (ulNrExcess && (pulHisto m_nMaxPixel) pulHistogram[i] = m_nMaxPixel; } } /* pImage - pointer to input/output image * This function calculates the new greylevel assignments of pixels within a submatrix * of the image with size uiXSize and uiYSize. This is done by a bilinear interpolation * between four different mappings in order to eliminate boundary artifacts. * It uses a division; since division is often an expensive operation, I added code to * perform a logical shift instead when feasible. */ void CLAHE:: Interpolate (unsigned char * pImage) { int x,y; int uiSubY,uiSubX,uiYU,uiYB,uiXL,uiXR; int *pulLU,*pulRU,*pulLB,*pulRB; unsigned char *pImPointer; //x,y都为0 pImPointer = pImage; uiSubY = m_nGridSize_Y>>1; uiSubX = m_nGridSize_X>>1; pulLU = &m_pMapArray[0]; pulRU = &m_pMapArray[0]; pulLB = &m_pMapArray[0]; pulRB = &m_pMapArray[0]; LineInterpolate(pImPointer,uiSubX,uiSubY,pulLU,pulRU,pulLB,pulRB); pImPointer += uiSubX; /* set pointer on next matrix */ //y为0 uiYU = 0; uiYB = 0; for (x=1; x >1; uiXL = m_nGridX - 1; uiXR = uiXL; pulLU = &m_pMapArray[m_nHistBins * uiXL]; pulRU = &m_pMapArray[m_nHistBins * uiXR]; pulLB = &m_pMapArray[m_nHistBins * uiXL]; pulRB = &m_pMapArray[m_nHistBins * uiXR]; LineInterpolate(pImPointer,uiSubX,uiSubY,pulLU,pulRU,pulLB,pulRB); pImPointer += uiSubX; /* set pointer on next matrix */ pImPointer += (uiSubY - 1) * m_nWidth; for (y=1; y > 1; pulLU = &m_pMapArray[m_nHistBins * uiYU * m_nGridX]; pulRU = &m_pMapArray[m_nHistBins * uiYU * m_nGridX]; pulLB = &m_pMapArray[m_nHistBins * uiYB * m_nGridX]; pulRB = &m_pMapArray[m_nHistBins * uiYB * m_nGridX]; LineInterpolate(pImPointer,uiSubX,uiSubY,pulLU,pulRU,pulLB,pulRB); pImPointer += uiSubX; /* set pointer on next matrix */ for (x=1; x > 1; uiXL = x - 1; uiXR = uiXL; pulLU = &m_pMapArray[m_nHistBins * (uiYU * m_nGridX + uiXL)]; pulRU = &m_pMapArray[m_nHistBins * (uiYU * m_nGridX + uiXR)]; pulLB = &m_pMapArray[m_nHistBins * (uiYB * m_nGridX + uiXL)]; pulRB = &m_pMapArray[m_nHistBins * (uiYB * m_nGridX + uiXR)]; LineInterpolate(pImPointer,uiSubX,uiSubY,pulLU,pulRU,pulLB,pulRB); pImPointer += uiSubX; /* set pointer on next matrix */ pImPointer += (uiSubY - 1) * m_nWidth; } //y为m_nGridY uiSubY = m_nGridSize_Y >> 1; uiYU = m_nGridY-1; uiYB = uiYU; //x为0 uiSubX = m_nGridSize_X >> 1; pulLU = &m_pMapArray[m_nHistBins * uiYU * m_nGridX]; pulRU = &m_pMapArray[m_nHistBins * uiYU * m_nGridX]; pulLB = &m_pMapArray[m_nHistBins * uiYB * m_nGridX]; pulRB = &m_pMapArray[m_nHistBins * uiYB * m_nGridX]; LineInterpolate(pImPointer,uiSubX,uiSubY,pulLU,pulRU,pulLB,pulRB); pImPointer += uiSubX; /* set pointer on next matrix */ for (x=1; x > 1; uiXL = x - 1; uiXR = uiXL; pulLU = &m_pMapArray[m_nHistBins * (uiYU * m_nGridX + uiXL)]; pulRU = &m_pMapArray[m_nHistBins * (uiYU * m_nGridX + uiXR)]; pulLB = &m_pMapArray[m_nHistBins * (uiYB * m_nGridX + uiXL)]; pulRB = &m_pMapArray[m_nHistBins * (uiYB * m_nGridX + uiXR)]; LineInterpolate(pImPointer,uiSubX,uiSubY,pulLU,pulRU,pulLB,pulRB); pImPointer += uiSubX; /* set pointer on next matrix */ pImPointer += (uiSubY - 1) * m_nWidth; } void CLAHE::ShiftInterpolate(unsigned char* pImage, int nSizeX, int nSizeY, int* pulMapLU,int* pulMapRU, int *pulMapLB, int *pulMapRB) { const int uiIncr = m_nWidth-nSizeX; /* Pointer increment after processing row */ unsigned char GreyValue; int uiNum = nSizeX*nSizeY; int x, y, nInvX, nInvY, uiShift = 0; while (uiNum >>= 1) uiShift++; /* Calculate 2log of uiNum */ for (y=0,nInvY=nSizeY; y > uiShift); } } } int CLAHE::LineInterpolate(unsigned char* pImage, int nSizeX, int nSizeY, int* pulMapLU,int* pulMapRU, int* pulMapLB, int* pulMapRB) { const int uiIncr = m_nWidth-nSizeX; /* Pointer increment after processing row */ unsigned char GreyValue; int uiNum = nSizeX*nSizeY; int x, y, nInvX, nInvY, uiShift = 0; for (y=0, nInvY=nSizeY; y 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/214129.html原文链接:https://javaforall.net
