Re-enabled the disable of the transfer function
This commit is contained in:
parent
2ebe81cb0e
commit
fef39b6215
@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include <osg/Geode>
|
#include <osg/Geode>
|
||||||
#include <osg/Geometry>
|
#include <osg/Geometry>
|
||||||
|
#include <osg/ImageUtils>
|
||||||
|
#include <osg/MatrixTransform>
|
||||||
#include <osg/io_utils>
|
#include <osg/io_utils>
|
||||||
|
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
@ -29,6 +31,308 @@
|
|||||||
#include <osgViewer/Viewer>
|
#include <osgViewer/Viewer>
|
||||||
|
|
||||||
|
|
||||||
|
class Histogram
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Histogram() {}
|
||||||
|
|
||||||
|
void analyse(const osg::Image* image, double interval=0.0);
|
||||||
|
|
||||||
|
void insertZeroBoundaryValues(float xMin=FLT_MAX, float xMax=-FLT_MAX);
|
||||||
|
|
||||||
|
osg::Node* createGraphicalRepresentation();
|
||||||
|
|
||||||
|
typedef std::map<float, float> ValueMap;
|
||||||
|
|
||||||
|
ValueMap& getValueMap() { return _valueMap; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
ValueMap _valueMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PopulateHistogram
|
||||||
|
{
|
||||||
|
|
||||||
|
PopulateHistogram(Histogram::ValueMap& valueMap):
|
||||||
|
_histogram(valueMap) {}
|
||||||
|
|
||||||
|
float cast(char v) { return v; }
|
||||||
|
float cast(unsigned char v) { return v; }
|
||||||
|
float cast(short v) { return v; }
|
||||||
|
float cast(unsigned short v) { return v; }
|
||||||
|
float cast(int v) { return v; }
|
||||||
|
float cast(unsigned int v) { return v; }
|
||||||
|
float cast(float v) { return v; }
|
||||||
|
float cast(double v) { return v; }
|
||||||
|
|
||||||
|
Histogram::ValueMap& _histogram;
|
||||||
|
|
||||||
|
void update(int v)
|
||||||
|
{
|
||||||
|
_histogram[v]+=1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void normalize()
|
||||||
|
{
|
||||||
|
double maxValue = 0;
|
||||||
|
for(Histogram::ValueMap::iterator itr = _histogram.begin();
|
||||||
|
itr != _histogram.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
if (itr->second>maxValue) maxValue = itr->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Histogram::ValueMap::iterator itr = _histogram.begin();
|
||||||
|
itr != _histogram.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
itr->second /= maxValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void luminance(float l) { update(l); }
|
||||||
|
void alpha(float a) { update(a); }
|
||||||
|
void luminance_alpha(float l, float a) { update(l); }
|
||||||
|
void rgb(float r, float g, float b) { update(r); }
|
||||||
|
void rgba(float r, float g, float b, float a) { update(a); }
|
||||||
|
};
|
||||||
|
|
||||||
|
void Histogram::analyse(const osg::Image* image, double interval)
|
||||||
|
{
|
||||||
|
PopulateHistogram populateHistogram(_valueMap);
|
||||||
|
readImage(image, populateHistogram);
|
||||||
|
populateHistogram.normalize();
|
||||||
|
|
||||||
|
for(Histogram::ValueMap::iterator itr = populateHistogram._histogram.begin();
|
||||||
|
itr != populateHistogram._histogram.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
OSG_NOTICE<<" "<<itr->first<<", "<<itr->second<<std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Histogram::insertZeroBoundaryValues(float xMin, float xMax)
|
||||||
|
{
|
||||||
|
if (_valueMap.empty())
|
||||||
|
{
|
||||||
|
if (xMin<xMax)
|
||||||
|
{
|
||||||
|
_valueMap[xMin] = 0.0;
|
||||||
|
_valueMap[xMax] = 0.0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float interval = 1.0f;
|
||||||
|
float min_gap_for_single_insertion = interval*1.5;
|
||||||
|
float min_gap_for_double_insertion = interval*2.5;
|
||||||
|
|
||||||
|
if (xMin<_valueMap.begin()->first)
|
||||||
|
{
|
||||||
|
_valueMap[xMin] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xMax>_valueMap.rbegin()->first)
|
||||||
|
{
|
||||||
|
_valueMap[xMax] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueMap::iterator itr = _valueMap.begin();
|
||||||
|
float previous_x = itr->first;
|
||||||
|
for(;
|
||||||
|
itr != _valueMap.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
float current_x = itr->first;
|
||||||
|
float gap = current_x-previous_x;
|
||||||
|
if (gap>min_gap_for_double_insertion)
|
||||||
|
{
|
||||||
|
_valueMap[previous_x+interval] = 0.0f;
|
||||||
|
_valueMap[current_x-interval] = 0.0f;
|
||||||
|
}
|
||||||
|
else if (gap>min_gap_for_single_insertion)
|
||||||
|
{
|
||||||
|
_valueMap[(previous_x+current_x)*0.5]=0.0f;
|
||||||
|
}
|
||||||
|
previous_x = current_x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Node* Histogram::createGraphicalRepresentation()
|
||||||
|
{
|
||||||
|
if (_valueMap.empty()) return 0;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
|
||||||
|
|
||||||
|
float xMin = _valueMap.begin()->first;
|
||||||
|
float xMax = _valueMap.rbegin()->first;
|
||||||
|
|
||||||
|
float depth = 0.0f;
|
||||||
|
float yMax = 0.0f;
|
||||||
|
|
||||||
|
// find yMax
|
||||||
|
for(ValueMap::iterator itr = _valueMap.begin();
|
||||||
|
itr != _valueMap.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
float y = itr->second;
|
||||||
|
if (y>yMax) yMax = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float xScale = 1.0f/(xMax-xMin);
|
||||||
|
float yScale = 1.0f/yMax;
|
||||||
|
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||||
|
transform->addChild(geode.get());
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
|
||||||
|
geode->addDrawable(geometry.get());
|
||||||
|
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
||||||
|
geometry->setVertexArray(vertices.get());
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
|
||||||
|
geometry->setColorArray(colours.get(), osg::Array::BIND_PER_PRIMITIVE_SET);
|
||||||
|
colours->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
|
||||||
|
colours->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
|
||||||
|
colours->push_back(osg::Vec4(1.0,1.0,1.0,0.1));
|
||||||
|
|
||||||
|
|
||||||
|
unsigned numColumnsRequired = _valueMap.size();
|
||||||
|
vertices->reserve(numColumnsRequired*3);
|
||||||
|
for(ValueMap::iterator itr = _valueMap.begin();
|
||||||
|
itr != _valueMap.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
float x = itr->first;
|
||||||
|
float y = itr->second;
|
||||||
|
|
||||||
|
vertices->push_back(osg::Vec3(x*xScale, 0.0f, depth));
|
||||||
|
vertices->push_back(osg::Vec3(x*xScale, y*yScale, depth));
|
||||||
|
vertices->push_back(osg::Vec3(x*xScale, yMax*yScale, depth));
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> background_primitives = new osg::DrawElementsUShort(GL_TRIANGLE_STRIP);
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> historgram_primitives = new osg::DrawElementsUShort(GL_TRIANGLE_STRIP);
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> outline_primitives = new osg::DrawElementsUShort(GL_LINE_STRIP);
|
||||||
|
for(unsigned int i=0; i<numColumnsRequired; ++i)
|
||||||
|
{
|
||||||
|
int iv = i*3;
|
||||||
|
|
||||||
|
background_primitives->push_back(iv+2);
|
||||||
|
background_primitives->push_back(iv+1);
|
||||||
|
|
||||||
|
historgram_primitives->push_back(iv+1);
|
||||||
|
historgram_primitives->push_back(iv+0);
|
||||||
|
|
||||||
|
outline_primitives->push_back(iv+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry->addPrimitiveSet(outline_primitives.get());
|
||||||
|
geometry->addPrimitiveSet(historgram_primitives.get());
|
||||||
|
geometry->addPrimitiveSet(background_primitives.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
//transform->setMatrix(osg::Matrix::scale(xScale/(maxX-minY), yScale/(yMax), 1.0f));
|
||||||
|
|
||||||
|
transform->setMatrix(osg::Matrix::scale(2.0,1.0,1.0)*osg::Matrix::rotate(osg::DegreesToRadians(90.0), osg::Vec3d(1.0,0.0,0.0)));
|
||||||
|
|
||||||
|
return transform.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Node* createGraphicalRepresentation(osg::TransferFunction1D* tf, unsigned int channel)
|
||||||
|
{
|
||||||
|
typedef osg::TransferFunction1D::ColorMap ColorMap;
|
||||||
|
ColorMap& colorMap = tf->getColorMap();
|
||||||
|
if (colorMap.empty()) return 0;
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::MatrixTransform> transform = new osg::MatrixTransform;
|
||||||
|
|
||||||
|
float xMin = colorMap.begin()->first;
|
||||||
|
float xMax = colorMap.rbegin()->first;
|
||||||
|
|
||||||
|
float depth = 0.0f;
|
||||||
|
float yMax = 0.0f;
|
||||||
|
|
||||||
|
// find yMax
|
||||||
|
for(ColorMap::iterator itr = colorMap.begin();
|
||||||
|
itr != colorMap.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
float y = itr->second[channel];
|
||||||
|
if (y>yMax) yMax = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
float xScale = 1.0f/(xMax-xMin);
|
||||||
|
float yScale = 1.0f/yMax;
|
||||||
|
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
|
||||||
|
transform->addChild(geode.get());
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry;
|
||||||
|
geode->addDrawable(geometry.get());
|
||||||
|
geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||||
|
geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
|
||||||
|
geometry->setVertexArray(vertices.get());
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Vec4Array> colours = new osg::Vec4Array;
|
||||||
|
geometry->setColorArray(colours.get(), osg::Array::BIND_PER_PRIMITIVE_SET);
|
||||||
|
colours->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
|
||||||
|
colours->push_back(osg::Vec4(1.0,1.0,1.0,1.0));
|
||||||
|
colours->push_back(osg::Vec4(1.0,1.0,1.0,0.1));
|
||||||
|
|
||||||
|
|
||||||
|
unsigned numColumnsRequired = colorMap.size();
|
||||||
|
vertices->reserve(numColumnsRequired*3);
|
||||||
|
for(ColorMap::iterator itr = colorMap.begin();
|
||||||
|
itr != colorMap.end();
|
||||||
|
++itr)
|
||||||
|
{
|
||||||
|
float x = itr->first;
|
||||||
|
float y = itr->second[channel];
|
||||||
|
|
||||||
|
vertices->push_back(osg::Vec3(x*xScale, 0.0f, depth));
|
||||||
|
vertices->push_back(osg::Vec3(x*xScale, y*yScale, depth));
|
||||||
|
vertices->push_back(osg::Vec3(x*xScale, yMax*yScale, depth));
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> background_primitives = new osg::DrawElementsUShort(GL_TRIANGLE_STRIP);
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> historgram_primitives = new osg::DrawElementsUShort(GL_TRIANGLE_STRIP);
|
||||||
|
osg::ref_ptr<osg::DrawElementsUShort> outline_primitives = new osg::DrawElementsUShort(GL_LINE_STRIP);
|
||||||
|
for(unsigned int i=0; i<numColumnsRequired; ++i)
|
||||||
|
{
|
||||||
|
int iv = i*3;
|
||||||
|
|
||||||
|
background_primitives->push_back(iv+2);
|
||||||
|
background_primitives->push_back(iv+1);
|
||||||
|
|
||||||
|
historgram_primitives->push_back(iv+1);
|
||||||
|
historgram_primitives->push_back(iv+0);
|
||||||
|
|
||||||
|
outline_primitives->push_back(iv+1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry->addPrimitiveSet(outline_primitives.get());
|
||||||
|
geometry->addPrimitiveSet(historgram_primitives.get());
|
||||||
|
geometry->addPrimitiveSet(background_primitives.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
//transform->setMatrix(osg::Matrix::scale(xScale/(maxX-minY), yScale/(yMax), 1.0f));
|
||||||
|
|
||||||
|
transform->setMatrix(osg::Matrix::scale(2.0,1.0,1.0)*osg::Matrix::rotate(osg::DegreesToRadians(90.0), osg::Vec3d(1.0,0.0,0.0)));
|
||||||
|
|
||||||
|
return transform.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename, float colorScale=1.0f)
|
osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename, float colorScale=1.0f)
|
||||||
{
|
{
|
||||||
@ -108,8 +412,16 @@ int main(int argc, char ** argv)
|
|||||||
OSG_NOTICE<<"No image found."<<std::endl;
|
OSG_NOTICE<<"No image found."<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Histogram histogram;
|
||||||
|
histogram.analyse(image.get());
|
||||||
|
|
||||||
viewer.setSceneData( model.get() );
|
osg::ref_ptr<osg::Group> group = new osg::Group;
|
||||||
|
group->addChild(histogram.createGraphicalRepresentation());
|
||||||
|
//if (tf.valid()) group->addChild(createGraphicalRepresentation(tf.get(),1));
|
||||||
|
|
||||||
|
viewer.setSceneData(group.get());
|
||||||
|
|
||||||
|
osgDB::writeNodeFile(*viewer.getSceneData(),"graph.osgt");
|
||||||
|
|
||||||
return viewer.run();
|
return viewer.run();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user