Introduced ImageLayer computeMinMax + rescaling methods, and use of rescaleToZeroToOneRange by default.
This commit is contained in:
parent
ba94ea8c7d
commit
78c2f98b7a
@ -2215,7 +2215,6 @@ int main( int argc, char **argv )
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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());
|
||||||
|
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user