void ossimHistogramEqualization::initializeLuts() { if(theForwardLut.size() != 0 || theInverseLut.size() != 0) { deleteLuts(); } if(!theAccumulationHistogram||!getHistogram()) { return; } ossimRefPtr<ossimMultiBandHistogram> accumHisto = theAccumulationHistogram->getMultiBandHistogram(0); ossimRefPtr<ossimMultiBandHistogram> histogram = getHistogram()->getMultiBandHistogram(0); ossimKeywordlist kwl; theAccumulationHistogram->saveState(kwl); if(accumHisto.valid()&&histogram.valid()) { long maxBands = accumHisto->getNumberOfBands(); for(long band = 0; band < maxBands; ++band) { // first we grab pointers to the histogram and the accumulation // histogram ossimRefPtr<ossimHistogram> h = accumHisto->getHistogram(band); ossimRefPtr<ossimHistogram> h2 = histogram->getHistogram(band); if(h.valid()&&h2.valid()) { // lets get the number of indices. ossim_uint32 numberOfIndices = (ossim_uint32)h2->GetRes(); vector<double> countForInverse(numberOfIndices); theForwardLut.push_back(new double[numberOfIndices]); theInverseLut.push_back(new double[numberOfIndices]); // let's grab the counts array const float* histoCounts = h->GetCounts(); // double maxIntensity = h2->GetMaxVal(); double maxIntensity = h2->GetRangeMax(); double maxCount = h->GetMaxCount(); // now pre compute the transforms double *forwardLut = theForwardLut[band]; double *inverseLut = theInverseLut[band]; // double minIntensity = h2->GetMinVal(); double minIntensity = h2->GetRangeMin(); double delta = maxIntensity-minIntensity; ossim_uint32 idx = 0; // clear out the inverse // for(idx = 0; idx < numberOfIndices; ++ idx) { inverseLut[idx] = ossim::nan(); } for(idx = 0; idx < numberOfIndices; ++ idx) { forwardLut[idx] = minIntensity + (histoCounts[idx]/maxCount)*delta; ossim_int32 inverseIdx = h2->GetIndex(forwardLut[idx]); if(inverseIdx >= 0) { inverseLut[inverseIdx] = minIntensity + delta*(idx/(ossim_float32)numberOfIndices); } } // now solve the inverse lut // ossim_uint32 idxStart = 0; ossim_uint32 idxEnd = 0; while((ossim::isnan(inverseLut[idxEnd]))&&(idxEnd <numberOfIndices)){ ++idxEnd;} if((idxStart!=idxEnd)&&(idxEnd<numberOfIndices)) { std::fill(inverseLut, inverseLut+idxEnd, inverseLut[idxEnd]); } idxStart = numberOfIndices-1; while((ossim::isnan(inverseLut[idxStart]))&&(idxStart > 0)){ --idxStart;} if(idxStart !=0) { std::fill(inverseLut+idxStart, inverseLut+numberOfIndices, inverseLut[idxStart]); } idxStart = 0; idxEnd = 0; ossim_float32 valueStart = 0.0; ossim_float32 valueEnd = 0.0; while(idxStart < numberOfIndices) { idxEnd = idxStart; if(ossim::isnan(inverseLut[idxStart])) { while(ossim::isnan(inverseLut[idxEnd])&&(idxEnd < (numberOfIndices-1))) ++idxEnd; double length = (idxEnd-idxStart)+1; valueEnd = inverseLut[idxEnd]; double deltaVal = (valueEnd-valueStart); ossim_uint32 tempIdx = idxStart; ossim_float32 count = 1.0; double t = 0.0; while(tempIdx < idxEnd) { t = (count/length); t = t>1.0?1.0:t; inverseLut[tempIdx] = valueStart + deltaVal*t; ++count; ++tempIdx; } idxStart = idxEnd; valueStart = valueEnd; } else { valueStart = inverseLut[idxStart]; ++idxStart; } } } } } }
ossimHistogramEqualization::~ossimHistogramEqualization() { deleteLuts(); }
rspfHistogramEqualization::~rspfHistogramEqualization() { deleteLuts(); }