diff --git a/include/openspace/util/histogram.h b/include/openspace/util/histogram.h index 85c027dfab..f5f2232634 100644 --- a/include/openspace/util/histogram.h +++ b/include/openspace/util/histogram.h @@ -67,9 +67,9 @@ public: void normalize(); void print() const; - void generateEqualizer(bool withoutHighestBin = false); + void generateEqualizer(); Histogram equalize(); - float equalize (float); + float equalize (float) const; /** * Entropy is a measure of histogram dispersion. @@ -77,9 +77,35 @@ public: */ float entropy() const; - float highestBinValue(bool equalized, int overBins=0); + /** + * finds the bin index with the highest frequency value + * @return The bin index + */ + int highestBin() const; + + /** + * Normalizes the bin index to a value between the + * highest data value (_maxValue) and the lowest (_minValue) + * + * @param bin The bin you want to know the corresponding data value of + * @return The normalized bin value. + */ + float realBinValue(int bin) const; float binWidth(); + /** + * Sets a bin to a certain value directly. This method is similar + * to add(float value, float repeat) but does the normalize the bin. + * Instead it access the bin value directly. It also changes the bin value + * instead of just adding upon it. + * + * @param bin The bin you want to change the value of + * @param value The value you want to change to + * + * @return true if successful + */ + bool setBin(int bin, float value); + void changeRange(float minValue, float maxValue); friend void operator<<(std::ostream& os, const Histogram& hist); diff --git a/modules/iswa/rendering/datacygnet.cpp b/modules/iswa/rendering/datacygnet.cpp index a18720d120..d7677abb48 100644 --- a/modules/iswa/rendering/datacygnet.cpp +++ b/modules/iswa/rendering/datacygnet.cpp @@ -69,8 +69,10 @@ bool DataCygnet::updateTexture(){ if(data.empty()) return false; - if(_autoFilter) + if(_autoFilter){ + _dataProcessor->calculateFilterValues(_dataOptions.value()); _backgroundValues.setValue(_dataProcessor->filterValues()); + } bool texturesReady = false; std::vector selectedOptions = _dataOptions.value(); diff --git a/modules/iswa/rendering/iswakameleongroup.cpp b/modules/iswa/rendering/iswakameleongroup.cpp index 9d27301e39..c030e5943d 100644 --- a/modules/iswa/rendering/iswakameleongroup.cpp +++ b/modules/iswa/rendering/iswakameleongroup.cpp @@ -1,26 +1,26 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2015 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #include #include diff --git a/modules/iswa/shaders/datasphere_fs.glsl b/modules/iswa/shaders/datasphere_fs.glsl index 6dfd182e9c..0feb1aee93 100644 --- a/modules/iswa/shaders/datasphere_fs.glsl +++ b/modules/iswa/shaders/datasphere_fs.glsl @@ -31,7 +31,7 @@ uniform sampler2D transferFunctions[6]; uniform int numTextures; uniform int numTransferFunctions; -uniform bool averageValues; +//uniform bool averageValues; uniform vec2 backgroundValues; uniform float transparency; diff --git a/modules/iswa/util/dataprocessor.cpp b/modules/iswa/util/dataprocessor.cpp index 2428c0f44a..9f2a34439b 100644 --- a/modules/iswa/util/dataprocessor.cpp +++ b/modules/iswa/util/dataprocessor.cpp @@ -138,7 +138,8 @@ void DataProcessor::calculateFilterValues(std::vector selectedOptions){ standardDeviation = _standardDeviation[option]; histogram = _unNormalizedhistograms[option]; - filterMid = histogram->highestBinValue(_useHistogram); + // get the real value for the highest bin + filterMid = histogram->realBinValue( histogram->highestBin() ); filterWidth = histogram->binWidth(); filterMid = normalizeWithStandardScore(filterMid, mean, standardDeviation, _normValues); @@ -149,7 +150,7 @@ void DataProcessor::calculateFilterValues(std::vector selectedOptions){ }else{ Histogram hist = _histograms[option]->equalize(); - filterMid = hist.highestBinValue(true); + filterMid = hist.highestBin() / (float)hist.numBins(); filterWidth = std::min(1.0f / (float)NumBins, 1.0f / 512.0f); } _filterValues += glm::vec2(filterMid-filterWidth, filterMid+filterWidth); @@ -204,8 +205,10 @@ void DataProcessor::add(std::vector>& optionValues, std::vect mean = (1.0f/_numValues[i])*_sum[i]; //const float* histData = _unNormalizedhistograms[i]->data(); - float histMin = _unNormalizedhistograms[i]->minValue(); - float histMax = _unNormalizedhistograms[i]->maxValue(); + //std::cout << "min: " << _min[i] << " max: " << _max[i] << std::endl; + //float histMin = _unNormalizedhistograms[i]->minValue(); + //float histMax = _unNormalizedhistograms[i]->maxValue(); + //std::cout << "histMin: " << histMin << " histMax: " << histMax << std::endl; int numBins = _unNormalizedhistograms[i]->numBins(); // float fit = IswaManager::ref().fit(); @@ -215,9 +218,9 @@ void DataProcessor::add(std::vector>& optionValues, std::vect float fit = _unNormalizedhistograms[i]->entropy(); _fitValues[i] = fit; - float max = normalizeWithStandardScore(histMax, mean, _standardDeviation[i], glm::vec2(_fitValues[i])); - float min = normalizeWithStandardScore(histMin, mean, _standardDeviation[i], glm::vec2(_fitValues[i])); - + float max = normalizeWithStandardScore(_max[i], mean, _standardDeviation[i], glm::vec2(_fitValues[i])); + float min = normalizeWithStandardScore(_min[i], mean, _standardDeviation[i], glm::vec2(_fitValues[i])); + std::cout << "min: " << min << " max: " << max << std::endl; std::shared_ptr newHist = std::make_shared(min, max, numBins); int length = _buildData[i].size(); @@ -226,12 +229,14 @@ void DataProcessor::add(std::vector>& optionValues, std::vect } _histograms[i] = newHist; - _histograms[i]->generateEqualizer(true); - - // _unNormalizedhistograms[i]->print(); - // ofs[i] << _fitValues[i] << " " << _histograms[i]->entropy() << std::endl; - // std::cout << _fitValues[i] << " " << _histograms[i]->entropy() << std::endl; - + //get the highest bin and sample its value (frequency) + int highestBin = _histograms[i]->highestBin(); + float highestBinValue = _histograms[i]->sample(highestBin); + //remove the highest bin to give a better equalization + _histograms[i]->setBin(highestBin, 0.0f); + _histograms[i]->generateEqualizer(); + //restore the highest bin + _histograms[i]->setBin(highestBin, highestBinValue); } diff --git a/modules/iswa/util/dataprocessor.h b/modules/iswa/util/dataprocessor.h index 5e36d27f1b..1b6d2c8405 100644 --- a/modules/iswa/util/dataprocessor.h +++ b/modules/iswa/util/dataprocessor.h @@ -70,6 +70,7 @@ public: * @return Processed data */ virtual std::vector processData(const std::string& data, const properties::SelectionProperty& dataOptions, const glm::size3_t& dimensions) = 0; + void calculateFilterValues(std::vector selectedOptions); void useLog(bool useLog); void useHistogram(bool useHistogram); @@ -82,7 +83,6 @@ public: protected: float processDataPoint(float value, int option); void initializeVectors(int numOptions); - void calculateFilterValues(std::vector selectedOptions); void add(std::vector>& optionValues, std::vector& sum); std::vector _min; diff --git a/modules/iswa/util/dataprocessorjson.cpp b/modules/iswa/util/dataprocessorjson.cpp index 6755cfa42f..bc346e5384 100644 --- a/modules/iswa/util/dataprocessorjson.cpp +++ b/modules/iswa/util/dataprocessorjson.cpp @@ -1,26 +1,26 @@ /***************************************************************************************** -* * -* OpenSpace * -* * -* Copyright (c) 2014-2016 * -* * -* Permission is hereby granted, free of charge, to any person obtaining a copy of this * -* software and associated documentation files (the "Software"), to deal in the Software * -* without restriction, including without limitation the rights to use, copy, modify, * -* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * -* permit persons to whom the Software is furnished to do so, subject to the following * -* conditions: * -* * -* The above copyright notice and this permission notice shall be included in all copies * -* or substantial portions of the Software. * -* * -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * -* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * -* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * -* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * -* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * -* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * -****************************************************************************************/ + * * + * OpenSpace * + * * + * Copyright (c) 2014-2016 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ #include #include #include @@ -134,8 +134,7 @@ std::vector DataProcessorJson::processData(const std::string& data, cons } } } - - calculateFilterValues(selectedOptions); + //calculateFilterValues(selectedOptions); return dataOptions; } return std::vector(); diff --git a/modules/iswa/util/dataprocessorkameleon.cpp b/modules/iswa/util/dataprocessorkameleon.cpp index cb6102070e..88fee7c188 100644 --- a/modules/iswa/util/dataprocessorkameleon.cpp +++ b/modules/iswa/util/dataprocessorkameleon.cpp @@ -130,7 +130,7 @@ std::vector DataProcessorKameleon::processData(const std::string& path, } } - calculateFilterValues(selectedOptions); + //calculateFilterValues(selectedOptions); return dataOptions; } return std::vector(numOptions, nullptr); diff --git a/modules/iswa/util/dataprocessortext.cpp b/modules/iswa/util/dataprocessortext.cpp index 815e298b7c..d01af67b2e 100644 --- a/modules/iswa/util/dataprocessortext.cpp +++ b/modules/iswa/util/dataprocessortext.cpp @@ -210,7 +210,7 @@ std::vector DataProcessorText::processData(const std::string& data, cons numValues++; } - calculateFilterValues(selectedOptions); + //calculateFilterValues(selectedOptions); return dataOptions; } diff --git a/src/util/histogram.cpp b/src/util/histogram.cpp index b139dd87c7..001b0a6baf 100644 --- a/src/util/histogram.cpp +++ b/src/util/histogram.cpp @@ -136,6 +136,7 @@ void Histogram::changeRange(float minValue, float maxValue){\ int binIndex = std::min( (float)floor(normalizedValue * _numBins), _numBins - 1.0f ); // [0, _numBins - 1] newData[binIndex] = oldData[i]; + //newData[binIndex] += oldData[i]; ? } _minValue = minValue; @@ -244,29 +245,27 @@ void Histogram::normalize() { * Old histogram value is the index of the array, and the new equalized * value will be the value at the index. */ -void Histogram::generateEqualizer(bool withoutHighestBin){ - float previousCdf = 0.0f; +void Histogram::generateEqualizer(){ + _equalizer = std::vector(_numBins, 0.0f); + // int numValues = _numValues; + // int highBin = -1; - int highestBin = -1; - float highestProbability = 0; - - if(withoutHighestBin){ - highestBin = 0; - for(int i=0; i<_numBins; i++){ - if(_data[i] > _data[highestBin]){ - highestBin = i; - } - } - highestProbability = _data[highestBin] / (float)_numValues; - } + // if(withoutHighestBin){ + // int highBin = highestBin(); + // std::cout << "highBin: " << highBin << std::endl; + // numValues -= (int)_data[highBin]; + // } + float previousCdf = 0.0f; for(int i = 0; i < _numBins; i++){ - float probability = highestProbability/(float)_numBins; - if(i != highestBin) - probability += _data[i] / (float)_numValues; - + // float probability = 0.0f; + // if(i != highBin) + // probability += _data[i] / (float)numValues; + float probability = _data[i] / (float)_numValues; + //if(withoutHighestBin) + //std::cout << "prob " << probability << std::endl; float cdf = previousCdf + probability; cdf = std::min(1.0f, cdf); _equalizer[i] = cdf * (_numBins-1); @@ -274,6 +273,17 @@ void Histogram::generateEqualizer(bool withoutHighestBin){ } } +bool Histogram::setBin(int bin, float value){ + if (bin < 0 || bin > _numBins) { + LWARNING("setBin: bin is out of range"); + return false; + } + _numValues -= _data[bin]; + _numValues += (int)value; + _data[bin] = value; + return true; +} + /* * Will return a equalized histogram */ @@ -291,7 +301,7 @@ Histogram Histogram::equalize(){ * Given a value within the domain of this histogram (_minValue < value < maxValue), * this method will use its equalizer to return a histogram equalized result. */ -float Histogram::equalize(float value){ +float Histogram::equalize(float value) const { // if (value < _minValue || value > _maxValue) { // LWARNING("Equalized value is is not within domain of histogram. min: " + std::to_string(_minValue) + " max: " + std::to_string(_maxValue) + " val: " + std::to_string(value)); // } @@ -327,26 +337,11 @@ void Histogram::print() const { std::cout << std::endl << std::endl << std::endl<< "==============" << std::endl; } -float Histogram::highestBinValue(bool equalized, int overBins){ +int Histogram::highestBin() const { int highestBin = 0; float highestValue = 0.0f; - - for(int i=0; i<_numBins; i++){ - float value = 0.0f; - int num = 0; - for(int j=0; j0){ - value += _data[i-j]; - num++; - } - if(i+j<_numBins){ - value += _data[i+j]; - num++; - } - } - - value += _data[i]; - value /= (float)++num; + for(int i=0; i < _numBins; i++){ + float value = _data[i]; if(value > highestValue){ highestBin = i; @@ -354,17 +349,20 @@ float Histogram::highestBinValue(bool equalized, int overBins){ } } - if(!equalized){ - float low = _minValue + (float(highestBin) / _numBins) * (_maxValue - _minValue); - float high = low + (_maxValue - _minValue) / float(_numBins); - return (high+low)/2.0; - }else{ - return highestBin/(float)_numBins; + return highestBin; +} + +float Histogram::realBinValue(int bin) const { + if (bin > _numBins || bin < 0) { + LWARNING("realBinValue: bin value should be between 0 - number of bin"); } + float low = _minValue + (float(bin) / _numBins) * (_maxValue - _minValue); + float high = low + (_maxValue - _minValue) / float(_numBins); + return (high+low)/2.0; } float Histogram::binWidth(){ - return (_maxValue-_minValue)/float(_numBins); + return (_maxValue-_minValue) / float(_numBins); } }