[osg-users] Problem with 3D image for scientific visualization

90 views
Skip to first unread message

Josiah Jideani

unread,
Jan 21, 2014, 3:56:32 AM1/21/14
to osg-...@lists.openscenegraph.org
Hi,

I am involved in a project where I have to build a 3D image from processed ultrasound data.  The 3D image is built up as a stack of 2D images. I inherited the code to build the 3D volume in Qt 4.7.1 on a linux machine.  The code has been working fine until I developed a new imaging algorithm and had to increase the size of the volume.  Here is the code snippet that sets up the viewer:


//image
    osg::Image* image = new osg::Image;
    image->allocateImage(_S, _T, _R, GL_RGBA, GL_FLOAT);
   
    for(int s = 0; s < image->s(); s++)
    {
        for(int t = 0; t < image->t(); t++)
        {
            for(int r = 0; r < image->r(); r++)
            {
                float*_data = (float*)(image->data(s, t, r));
               
                _data[0] = 0.0f;
                _data[1] = 0.0f;
                _data[2] = 1.0f;
                _data[3] = 0.1f;
            }
        }
    }
   
    float image_s = (float)(image->s());
    float image_t = (float)(image->t())/10.0f;
    float image_r = (float)(image->r());

    osg::ref_ptr<osg::RefMatrix> matrix = new osg::RefMatrix();

    osgVolume::Locator* locator = new osgVolume::Locator(*matrix.get());
    locator->setTransformAsExtents(0.0f, 0.0f, image_s, image_t, 0.0f, image_r);
   
    osgVolume::Layer* layer = new osgVolume::ImageLayer(image);
    layer->setLocator(locator);
   
    osgVolume::VolumeTile* tile = new osgVolume::VolumeTile;
    tile->setLocator(locator);
    tile->setLayer(layer);
    tile->setEventCallback(new osgVolume::PropertyAdjustmentCallback());

    hss::ShaderModel shaderModel = hss::StanderdShaderModel;
    hss::ShaderTechnique shaderTechnique = hss::RayTracedShaderTechnique;
    float alphaFunc=0.001;
   
    switch (shaderTechnique)
    {
        case (hss::RayTracedShaderTechnique):
        {
            osgVolume::SwitchProperty* sp = new osgVolume::SwitchProperty;
            sp->setActiveProperty(0);
           
            osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(alphaFunc);
            osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(0.005);
            osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(1.0);
            osgVolume::TransferFunctionProperty* tfp = 0;
           
            {
                // Standard
                osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty;
                cp->addProperty(ap);
                cp->addProperty(sd);
                cp->addProperty(tp);
                if (tfp) cp->addProperty(tfp);
               
                sp->addProperty(cp);
            }
           
            {
                // Light
                osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty;
                cp->addProperty(ap);
                cp->addProperty(sd);
                cp->addProperty(tp);
                cp->addProperty(new osgVolume::LightingProperty);
                if (tfp) cp->addProperty(tfp);
               
                sp->addProperty(cp);
            }
           
            {
                // IsoSurface
                osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty;
                cp->addProperty(sd);
                cp->addProperty(tp);
                cp->addProperty(new osgVolume::IsoSurfaceProperty(alphaFunc));
                if (tfp) cp->addProperty(tfp);
               
                sp->addProperty(cp);
            }
           
            {
                // MaximumIntensityProjection
                osgVolume::CompositeProperty* cp = new osgVolume::CompositeProperty;
                cp->addProperty(ap);
                cp->addProperty(sd);
                cp->addProperty(tp);
                cp->addProperty(new osgVolume::MaximumIntensityProjectionProperty);
                if (tfp) cp->addProperty(tfp);
               
                sp->addProperty(cp);
            }
           
            switch(shaderModel)
            {
                case(hss::StanderdShaderModel):                     sp->setActiveProperty(0); break;
                case(hss::LightShaderModel):                        sp->setActiveProperty(1); break;
                case(hss::IsosurfaceShaderModel):                   sp->setActiveProperty(2); break;
                case(hss::MaximumIntensityProjectionShaderModel):   sp->setActiveProperty(3); break;
            }
            layer->addProperty(sp);
           
            tile->setVolumeTechnique(new osgVolume::RayTracedTechnique);
        }
        break;
       
        default:
        {
            layer->addProperty(new osgVolume::AlphaFuncProperty(alphaFunc));
            tile->setVolumeTechnique(new osgVolume::FixedFunctionTechnique);
        }
    }
   
    //volume
    osgVolume::Volume* volume = new osgVolume::Volume;
    volume->addChild(tile);
   
    osg::Group* rootBox = new osg::Group;
    rootBox->addChild(volume);

The typical values for _S, _T, and _R used in the allocateImage() function call are 127, 2048 and 63 respectively and they are represent the exact size of the data matrix.

I observed that when _T is increased to 4096, the mapping from data to the 3D image becomes distorted and the image seems to shift to the 2nd  half of the volume.  While debugging I noticed that when I only initialize the pixels in the first half of the 3D image ( for(int t = 0; t < image->t()/2; t++) ), I get something that looks like Fig. 1 instead of Fig. 2.  In Fig. 1, it seems to be initializing 32 slices of the entire volume instead of the all 63 slices of only the first half (like in Fig 2), as a result the location of the representation of my targets in the 3D image does not correlate with that actual location of the targets in the real world.

Could you help me understand why this is happening and the possible solutions to this?  I am quite new to OSG so I request that you be patient with me if I ask dumb questions?

PS: I have an nvidia geforce GTX 480 graphics card on the system.

Thank you
 

Regards,

Josiah
Fig 1.jpeg
Fig 2.jpeg

Robert Osfield

unread,
Jan 21, 2014, 4:43:18 AM1/21/14
to OpenSceneGraph Users
Hi Josiah,

Try changing the pixel format from GL_FLOAT to GL_UNSIGNED_BYTE to see if it's a memory issue.

Robert.


_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Josiah Jideani

unread,
Jan 21, 2014, 5:14:28 AM1/21/14
to osg-...@lists.openscenegraph.org

Hi Robert,

Thanks for your reply.

I changed the pixel format to GL_UNSIGNED_BYTE and alternately changed the pixel initialization values between the ranges of 0.0f - 1.0f and 0 - 255 but neither worked.  It now only initializes 32 slices of one face of the volume (see attached picture).


Regards,

Josiah


--
You received this message because you are subscribed to a topic in the Google Groups "OpenSceneGraph Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/osg-users/wkva7tXcbLk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to osg-users+...@googlegroups.com.
To post to this group, send email to osg-...@googlegroups.com.
Visit this group at http://groups.google.com/group/osg-users.
For more options, visit https://groups.google.com/groups/opt_out.



Fig 3.jpeg

Ulrich Hertlein

unread,
Jan 21, 2014, 5:21:34 AM1/21/14
to OpenSceneGraph Users
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Hi Josiah,

On 21/01/2014 9:56, Josiah Jideani wrote:
> ...

> The code has been working fine until I developed a new imaging algorithm and had to
> increase the size of the volume. Here is the code snippet that sets up the viewer:
> ... The typical values for _S, _T, and _R used in the allocateImage() function call
> are 127, 2048 and 63 respectively and they are represent the exact size of the data
> matrix.

What were the previous dimensions for the 3D texture? I haven't used 3D textures in
ages, but those dimensions look suspicious to me...

You might want to enable debug output and check for errors there.
(Unless the previous dimensions were somewhat similar and I'm way behind 3D texture usage.)

Cheers,
/ulrich

- --
Fingerprint 0227 8EE1 2C64 8EF4 DA11 9864 FF16 0114 B9DA 3318
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQEcBAEBCAAGBQJS3kotAAoJEP8WARS52jMYltsH/21DKEvILbdLNZejEXgJeiPy
xRPTV8bTkdQQcYTGpye4JF6gkSV7oIIf8VskYNrZSqfGmPv8kMPGRdGdczHjav08
B0SIxn+ORd/DdD+UXXVf8jQ8JI+HovwUcynW482C4LiVChIeOqQTz9SGXHyLZLFu
q7u8YbkhEHPo9SqK3dCahvicd8hMS0B9eO78hqmWFeZmctRJWrBwyqc7cv6dGfDb
1Y7J2AkwSituQ8ZaXrcG2E3EBH/6VTW2GariqZIOe//FxMn1ZW29FBD6paSu/mAD
4Ufqtn9TX5wkGzRD6ocEEMXjQRPGgZtUlcd2u6jJIkuvXA7tnzi6BdSbLV1vF18=
=ev/Z
-----END PGP SIGNATURE-----

Josiah Jideani

unread,
Jan 21, 2014, 5:39:48 AM1/21/14
to osg-...@lists.openscenegraph.org
Hi Ulrich,

Thanks for replying.

I think I phrased that sentence wrong.  I made it seem like it was my modifications causing it, but that is not the case because I recreated the problem without my modifications.  The previous dimension for the 3D texture is 127x2048x63, and the problem occurs when I change the dimension to 127x4096x63.

Regards,
Josiah


Sebastian Messerschmidt

unread,
Jan 21, 2014, 5:50:46 AM1/21/14
to OpenSceneGraph Users
Hi Josiah,

Can you check the GL_MAX_3D_TEXTURE_SIZE with something like GPU Caps Viewer?
Even my GTX680 only supports 2048. So basically you might be hitting the limit.

cheers
Sebastian

Josiah Jideani

unread,
Jan 21, 2014, 9:11:46 AM1/21/14
to osg-...@lists.openscenegraph.org
Hi Sebastian,

I checked the KInfocenter on OpenSUSE and it says the Max. 3D texture size is 2048.  The OpenGL wiki says "For 3D textures, no dimension can be greater than GL_MAX_3D_TEXTURE_SIZE in size."
So I guess I'm violating this criteria and hence the wierd result.  This leads me to my next question: is it possible to still squeeze my data which is say (127x4098x63) into a 3D image that is (127x2048x63) and still preserve the data->image mapping?

Regards,
Josiah

Christian Buchner

unread,
Jan 21, 2014, 9:15:19 AM1/21/14
to OpenSceneGraph Users

can't you split your data set across several 3D textures and join these back together during the visualization phase?




2014/1/21 Josiah Jideani <josh.j...@gmail.com>

Josiah Jideani

unread,
Jan 22, 2014, 4:37:31 AM1/22/14
to osg-...@lists.openscenegraph.org
Hi Christian,

Thanks for the suggestion.  I will try that. It would involve considerable changes to the visualization setup and update callbacks.

Regards,
Josiah


Reply all
Reply to author
Forward
0 new messages