[osg-users] Volume rendering issues...

Robert Osfield robert.osfield at gmail.com
Thu Jul 26 06:29:46 PDT 2018


Hi Tom.

My best guess would be that the ITK image data is being deleted prior
to the graphics thread gets a chance copy the data into OpenGL.  Try
either copying the data into the osg::Image and let osg::Image then
manage the lifetime of it's own data, or prevent the ITK image data
from getting deleted prior to the osg::Texture3D being used in the
graphics thread - for instance keeping the ITK image object around for
the lifetime of the app, or perhaps more elegantly assigning the ITK
image data via a adapter class that you write to assign it to the
osg:Image as user data.

Robert.
On Thu, 26 Jul 2018 at 14:04, Tom Williamson <tom.williamson at rmit.edu.au> wrote:
>
> Hi gang,
>
> Thanks for all the work on OSG, is rad. I'm currently having a problem with the rendering of a volume, here's what I'm trying to do:
> - I'm using ITK to read a NIFTI file, (segmentation of a bone). The file contains zeros (background) and ones (object), format is unsigned short.
> - I am then normalizing/scaling this and converting it to an osg::Image.
> - I am then attempting to convert this to an osgVolume and display an iso-surface, or at this stage any kind of volume rendering.
> - All the reading, conversion etc. seems to work okay, but I'm getting a read access violation on line 408 of Texture3d.cpp (specifically:Exception thrown at 0x00007FFE64D576B0 (ig9icd64.dll) in RobotSimulation.exe: 0xC0000005: Access violation reading location 0x000002F5732EE070.)
>
> I'm pretty sure I'm just forgetting something very obvious, but if anyone could point out what it is that I'm doing wrong that would be much appreciated. I've put a cut down example of the code below (pretty rough).
> I know that the data is definitely in the osg::image object (wrote it to file, calculated min and max), so I don't necessarily think the conversion is the problem (though could very well be wrong). I'm on a Windows 10 laptop, with a built in Intel graphics card (Intel HD Graphics 620, drivers are up to date), opengl is version 4.5.
> Thanks very much for the help, let me know if you need any other info. Cheers,
> Tom
>
> PS: I'm happy to provide some example data if needed, but I guess this would be more or less the same for any data loaded through ITK and converted to OSG.
> PPS: I've left the code as normal text, it looked somewhat unreadable in the preview, so sorry about that.
>
> [code]
> osg::ref_ptr<osgVolume::Volume> getOsgVolume(std::string filename)
> {
>         osg::ref_ptr<osg::Image> osgImage = new osg::Image();
>         itk::NiftiImageIOFactory::RegisterOneFactory();
>         itk::ImageIOBase::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(filename.c_str(), itk::ImageIOFactory::ReadMode);
>         imageIO->SetFileName(filename);
>         imageIO->ReadImageInformation();
>         osg::ref_ptr<osgVolume::Volume> volume = new osgVolume::Volume;
>
>         std::cout << "numDimensions: " << imageIO->GetNumberOfDimensions() << std::endl;
>         std::cout << "component type: " << imageIO->GetComponentTypeAsString(imageIO->GetComponentType()) << std::endl;
>         std::cout << "pixel type: " << imageIO->GetPixelTypeAsString(imageIO->GetPixelType()) << std::endl;
>
>         if (imageIO->GetNumberOfDimensions() == 3) {
>                 typedef itk::Image<unsigned short, 3>  imType;
>                 typedef itk::ImageFileReader<imType> imTypeReader;
>
>                 imTypeReader::Pointer imageReader = imTypeReader::New();
>                 imageReader->SetFileName(imageIO->GetFileName());
>                 imageReader->Update();
>
>                 imType::RegionType region;
>                 imType::IndexType start;
>                 imType::SizeType size;
>
>                 for (int i = 0; i < imageIO->GetNumberOfDimensions(); ++i) {
>                         start[i] = 0;
>                         size[i] = imageIO->GetDimensions(i);
>                 }
>
>                 region.SetSize(size);
>                 region.SetIndex(start);
>                 typedef itk::MultiplyImageFilter< imType> miType;
>                 miType::Pointer mif = miType::New();
>                 mif->SetInput(imageReader->GetOutput());
>                 mif->SetConstant(pow(2, 16) - 1);
>                 mif->Update();
>                 imType::Pointer itkImage = mif->GetOutput();
>                 region = itkImage->GetBufferedRegion();
>                 size = region.GetSize();
>                 start = region.GetIndex();
>
>                 unsigned int width = size[0];
>                 unsigned int height = size[1];
>                 unsigned int depth = size[2];
>
>                 osg::RefMatrix* matrix = new osg::RefMatrix;
>
>                 std::cout << "width = " << width << " height = " << height << " depth = " << depth << std::endl;
>                 for (unsigned int i = 0; i<3; ++i)
>                 {
>                         (*matrix)(i, i) = itkImage->GetSpacing()[i];
>                 }
>
>                 osgImage->setImage(width, height, depth, GL_LUMINANCE16, GL_LUMINANCE, GL_UNSIGNED_SHORT, (BYTE*)itkImage->GetBufferPointer(), osg::Image::NO_DELETE, 1, width);
>
>                 // Setup the transfer function
>                 osg::ref_ptr<osg::TransferFunction1D> transferFunction = new osg::TransferFunction1D;
>                 transferFunction->setColor(0.0, osg::Vec4(1.0, 0.0, 0.0, 0.0));
>                 transferFunction->setColor(0.5, osg::Vec4(1.0, 1.0, 0.0, 0.5));
>                 transferFunction->setColor(1.0, osg::Vec4(0.0, 0.0, 1.0, 1.0));
>
>                 // Setup the volume
>                 osgVolume::ImageDetails* details = new osgVolume::ImageDetails;
>                 details->setMatrix(matrix);
>                 osgImage->setUserData(details);
>                 matrix->preMult(osg::Matrix::scale(double(osgImage->s()), double(osgImage->t()), double(osgImage->r())));
>                 osg::ref_ptr<osgVolume::VolumeTile> tile = new osgVolume::VolumeTile;
>                 volume->addChild(tile.get());
>                 osg::ref_ptr<osgVolume::ImageLayer> layer = new osgVolume::ImageLayer(osgImage.get());
>                 layer->setLocator(new osgVolume::Locator(*matrix));
>                 tile->setLocator(new osgVolume::Locator(*matrix));
>                 tile->setLayer(layer.get());
>
>                 // Rest of this is setting up the volume rendering...
>                 float alphaFunc = 0.02f;
>
>                 osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(alphaFunc);
>                 osgVolume::IsoSurfaceProperty* isop = new osgVolume::IsoSurfaceProperty(alphaFunc);
>                 osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(0.5f);
>                 osgVolume::SampleDensityWhenMovingProperty* sdwm = new osgVolume::SampleDensityWhenMovingProperty(0.1);
>                 osgVolume::SampleRatioProperty* sr = new osgVolume::SampleRatioProperty(1.0f);
>                 osgVolume::SampleRatioWhenMovingProperty* srwm = new osgVolume::SampleRatioWhenMovingProperty(0.1);
>                 osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(1.0);
>                 osgVolume::TransferFunctionProperty* tfp = new osgVolume::TransferFunctionProperty(transferFunction.get());
>                 osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty;
>                 cp->addProperty(sr);
>                 cp->addProperty(tp);
>                 cp->addProperty(isop);
>                 cp->addProperty(sdwm);
>                 cp->addProperty(tfp);
>
>                 layer->addProperty(cp);
>                 tile->setVolumeTechnique(new osgVolume::MultipassTechnique);
>
>         }
>         std::cout << "Valid: " << volume.valid() << std::endl;
>         return volume;
>
> }
> [/code]
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=74384#74384
>
>
>
>
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


More information about the osg-users mailing list