Introduced ImageLayer computeMinMax + rescaling methods, and use of rescaleToZeroToOneRange by default.

This commit is contained in:
Robert Osfield 2009-01-16 10:23:17 +00:00
parent ba94ea8c7d
commit 78c2f98b7a
5 changed files with 92 additions and 5 deletions

View File

@ -2215,7 +2215,6 @@ int main( int argc, char **argv )
} }
break; break;
} }
break;
}; };
} }

View File

@ -124,6 +124,18 @@ class OSGVOLUME_EXPORT ImageLayer : public Layer
/** Return const image associated with layer. */ /** Return const image associated with layer. */
virtual const osg::Image* getImage() const { return _image.get(); } virtual const osg::Image* getImage() const { return _image.get(); }
/** Compute the min and max pixel colors.*/
bool computeMinMax(osg::Vec4& min, osg::Vec4& max);
/** Apply color transformation to pixels using c' = offset + c * scale .*/
void offsetAndScaleImage(const osg::Vec4& offset, const osg::Vec4& scale);
/** Compute the min max range of the image, and then remap this to a 0 to 1 range.*/
void rescaleToZeroToOneRange();
/** Compute the min color component of the image and then translate and pixels by this offset to make the new min component 0.*/
void translateMinToZero();
virtual void dirty(); virtual void dirty();
virtual void setModifiedCount(unsigned int value); virtual void setModifiedCount(unsigned int value);
virtual unsigned int getModifiedCount() const; virtual unsigned int getModifiedCount() const;

View File

@ -122,7 +122,8 @@ class ReaderWriterDICOM : public osgDB::ReaderWriter
osg::ref_ptr<osgVolume::VolumeTile> tile = new osgVolume::VolumeTile; osg::ref_ptr<osgVolume::VolumeTile> tile = new osgVolume::VolumeTile;
tile->setVolume(volume.get()); tile->setVolume(volume.get());
osg::ref_ptr<osgVolume::Layer> layer= new osgVolume::ImageLayer(result.getImage()); osg::ref_ptr<osgVolume::ImageLayer> layer= new osgVolume::ImageLayer(result.getImage());
layer->rescaleToZeroToOneRange();
tile->setLayer(layer.get()); tile->setLayer(layer.get());

View File

@ -12,6 +12,8 @@
#include <osgDB/Input> #include <osgDB/Input>
#include <osgDB/Output> #include <osgDB/Output>
#include <osgDB/ParameterOutput> #include <osgDB/ParameterOutput>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgVolume/VolumeTile> #include <osgVolume/VolumeTile>
@ -44,10 +46,31 @@ bool ImageLayer_readLocalData(osg::Object& obj, osgDB::Input &fr)
if (!deferExternalLayerLoading) if (!deferExternalLayerLoading)
{ {
osg::ref_ptr<osg::Image> image = fr.readImage(filename.c_str());
osgDB::FileType fileType = osgDB::fileType(filename);
if (fileType == osgDB::FILE_NOT_FOUND)
{
filename = osgDB::findDataFile(filename);
fileType = osgDB::fileType(filename);
}
osg::ref_ptr<osg::Image> image;
if (fileType == osgDB::DIRECTORY)
{
image = osgDB::readImageFile(filename+".dicom");
}
else if (fileType == osgDB::REGULAR_FILE)
{
image = osgDB::readImageFile( filename );
}
osg::notify(osg::NOTICE)<<"image "<<filename<<" pixelFormat "<<std::hex<<image->getPixelFormat()<<" textureFormat "<<image->getInternalTextureFormat()<<" dataType "<<image->getDataType()<<std::endl;
if (image.valid()) if (image.valid())
{ {
layer.setImage(image.get()); layer.setImage(image.get());
layer.rescaleToZeroToOneRange();
} }
} }
} }

View File

@ -13,13 +13,14 @@
#include <osgVolume/Layer> #include <osgVolume/Layer>
#include <osg/ImageUtils>
#include <osg/Notify> #include <osg/Notify>
#include <osg/io_utils> #include <osg/io_utils>
using namespace osgVolume; using namespace osgVolume;
Layer::Layer(): Layer::Layer():
_minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), _minFilter(osg::Texture::LINEAR),
_magFilter(osg::Texture::LINEAR) _magFilter(osg::Texture::LINEAR)
{ {
} }
@ -110,7 +111,58 @@ unsigned int ImageLayer::getModifiedCount() const
else return _image->getModifiedCount(); else return _image->getModifiedCount();
} }
bool ImageLayer::computeMinMax(osg::Vec4& minValue, osg::Vec4& maxValue)
{
if (_image.valid()) return osg::computeMinMax(_image.get(), minValue, maxValue);
else return false;
}
void ImageLayer::offsetAndScaleImage(const osg::Vec4& offset, const osg::Vec4& scale)
{
if (!_image) return;
osg::offsetAndScaleImage(_image.get(), offset, scale);
}
void ImageLayer::rescaleToZeroToOneRange()
{
osg::Vec4 minValue, maxValue;
if (computeMinMax(minValue, maxValue))
{
float minComponent = minValue[0];
minComponent = osg::minimum(minComponent,minValue[1]);
minComponent = osg::minimum(minComponent,minValue[2]);
minComponent = osg::minimum(minComponent,minValue[3]);
float maxComponent = maxValue[0];
maxComponent = osg::maximum(maxComponent,maxValue[1]);
maxComponent = osg::maximum(maxComponent,maxValue[2]);
maxComponent = osg::maximum(maxComponent,maxValue[3]);
float scale = 0.99f/(maxComponent-minComponent);
float offset = -minComponent * scale;
offsetAndScaleImage(osg::Vec4(offset, offset, offset, offset),
osg::Vec4(scale, scale, scale, scale));
}
}
void ImageLayer::translateMinToZero()
{
osg::Vec4 minValue, maxValue;
if (computeMinMax(minValue, maxValue))
{
float minComponent = minValue[0];
minComponent = osg::minimum(minComponent,minValue[1]);
minComponent = osg::minimum(minComponent,minValue[2]);
minComponent = osg::minimum(minComponent,minValue[3]);
float offset = -minComponent;
offsetAndScaleImage(osg::Vec4(offset, offset, offset, offset),
osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
}
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //