Discussion:
[osg-users] osg::Image::setImage problem
Evan Tsai
2017-02-18 02:38:12 UTC
Permalink
Hi,

I've been using osg::Image::setImage to display gray scale bitmaps (x-rays) successfully. Recently I received some image data which looks correct but shows up twisted in OSG (see attachment: Twisted.bmp). I've verified that the pixel data is correct by dumping a .bmp file (see attachment: Correct.bmp).

I am wondering, why would this method works fine for most gray scale bitmaps but not for others? Are there certain settings that could have caused such a problem?

Thank you!

Cheers,
Evan

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=70239#70239




Attachments:
http://forum.openscenegraph.org//files/correct_145.bmp
http://forum.openscenegraph.org//files/twisted_262.bmp
Robert Osfield
2017-02-18 10:04:41 UTC
Permalink
Hi Evan,

This type of problem would either be down to the texture coordinates
being set up wrong or the reading of the image file being broken in
some way. You don't provide any additionally details beyond the
output results so there isn't any way for us to say which one is most
likely.

Could you provide the source data and guidance on how to reproduce the issue?

I.e. osgviewer --image good.bmp
osgviewer --image bad.gmp

Also provide details on which OSG version, platform, hardware you are
working on as there may be chance that these could have an impact on
the issue. It can be useful to check github's history for source
files to see if any commits describe addressing an issue similar to
what you see. I.e. look at the bmp plugin source.

Another tack you can take is to try converting your problem source
data to another file format to see if the new file format works. Also
try loading the problem files in a range of other image rendering
tools to see if they all work fine.

Robert.
Post by Evan Tsai
Hi,
I've been using osg::Image::setImage to display gray scale bitmaps (x-rays) successfully. Recently I received some image data which looks correct but shows up twisted in OSG (see attachment: Twisted.bmp). I've verified that the pixel data is correct by dumping a .bmp file (see attachment: Correct.bmp).
I am wondering, why would this method works fine for most gray scale bitmaps but not for others? Are there certain settings that could have caused such a problem?
Thank you!
Cheers,
Evan
------------------
http://forum.openscenegraph.org/viewtopic.php?p=70239#70239
http://forum.openscenegraph.org//files/correct_145.bmp
http://forum.openscenegraph.org//files/twisted_262.bmp
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Sebastian Messerschmidt
2017-02-18 12:42:10 UTC
Permalink
Hi Evan,
Post by Evan Tsai
Hi,
I've been using osg::Image::setImage to display gray scale bitmaps (x-rays) successfully. Recently I received some image data which looks correct but shows up twisted in OSG (see attachment: Twisted.bmp). I've verified that the pixel data is correct by dumping a .bmp file (see attachment: Correct.bmp).
It would be probably best if you could show the actual code where you
assign the data. Most likely you're messing the format up.

Cheers
Sebastian
Post by Evan Tsai
I am wondering, why would this method works fine for most gray scale bitmaps but not for others? Are there certain settings that could have caused such a problem?
Thank you!
Cheers,
Evan
------------------
http://forum.openscenegraph.org/viewtopic.php?p=70239#70239
http://forum.openscenegraph.org//files/correct_145.bmp
http://forum.openscenegraph.org//files/twisted_262.bmp
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Evan Tsai
2017-02-18 16:38:27 UTC
Permalink
Thank you very much for helping. Below is how we make the call.

This has been working fine until very recently we received scan data from some CBCT scanners that we haven't encountered before. However those scans could be viewed correctly in all popular DICOM viewers in the market. As mentioned, I also took the pixel data and dumped it into a .bmp file, which looks correct. So the only possibility seems to be that we are missing some setting here......

I did try changing the texture coordinates around but that doesn't change the twisted nature of the display.

I also tried changing `packing' from 1 to 0 but that crashes the software.

Is there anything in particular that one needs to set for `rowLength'?



osg::Geode* pGeode = new osg::Geode;

osg::Vec3 v1(pBottomLeft[0], pBottomLeft[1], pBottomLeft[2]);
osg::Vec3 v2(pBottomRight[0], pBottomRight[1], pBottomRight[2]);
osg::Vec3 v3(pTopRight[0], pTopRight[1], pTopRight[2]);
osg::Vec3 v4(pTopLeft[0], pTopLeft[1], pTopLeft[2]);

osg::Geometry* geom = new osg::Geometry;
geom->setDataVariance(osg::Object::DYNAMIC);
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = v1;
(*vertices)[1] = v2;
(*vertices)[2] = v3;
(*vertices)[3] = v4;
geom->setVertexArray(vertices);

osg::Vec2Array* texcoords = new osg::Vec2Array(4);
(*texcoords)[0].set(0.0f, 0.0f);
(*texcoords)[1].set(1, 0.0f);
(*texcoords)[2].set(1, 1);
(*texcoords)[3].set(0.0f, 1);

geom->setTexCoordArray(0, texcoords);

osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(1);
(*normals)[0].set(0.0f, -1.0f, 0.0f);
geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f, 1.0f, 1.0f, 1.0f);
geom->setColorArray(colors, osg::Array::BIND_OVERALL);

geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
geom->setUseDisplayList(false);
osg::ref_ptr<osg::Image> img = new osg::Image;

img->setImage(image.GetWidth(), image.GetHeight(), 1,
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, image.GetPixelData(),
osg::Image::USE_NEW_DELETE);

//osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile("C:\\Users\\rupeshb\\Pictures\\error.bmp");

//osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile(filename);

osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(img);
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat;
texmat->setScaleByTextureRectangleSize(true);
// setup state
osg::ref_ptr<osg::StateSet> state = geom->getOrCreateStateSet();
state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
state->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);

state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

pGeode->addDrawable(geom);
addChild(pGeode);

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=70254#70254
Robert Osfield
2017-02-18 16:54:24 UTC
Permalink
HI Evan,

My best guess is that the packing of the data in each row is out, as
your Image::setData(..) call doesn't supply all the parameters
explicitly it will default to a packing of 1 byte.

For instance if the packing for your source data is 4 bytes, and all
you previous image data has a width with multiple of 4 then there
won't be any mismatch when using a 1 byte packing as it will select
the same width. However, if you use a width such as 3 then the source
data with a 4 byte packing would round up to 4 bytes width, but the
osg::Image::setImage() call you are using says just use 1 byte packing
so selects a width of 3. This will result in a each successive row
starting 1 byte off and leading to the "twist" you see.

Check the spec of your image reading code/file format to see what the
row packing is. Also have a look at the docs for
osg::Image::setImage(..), note the optional packing and rowLength
parameters.

Robert
Post by Evan Tsai
Thank you very much for helping. Below is how we make the call.
This has been working fine until very recently we received scan data from some CBCT scanners that we haven't encountered before. However those scans could be viewed correctly in all popular DICOM viewers in the market. As mentioned, I also took the pixel data and dumped it into a .bmp file, which looks correct. So the only possibility seems to be that we are missing some setting here......
I did try changing the texture coordinates around but that doesn't change the twisted nature of the display.
I also tried changing `packing' from 1 to 0 but that crashes the software.
Is there anything in particular that one needs to set for `rowLength'?
osg::Geode* pGeode = new osg::Geode;
osg::Vec3 v1(pBottomLeft[0], pBottomLeft[1], pBottomLeft[2]);
osg::Vec3 v2(pBottomRight[0], pBottomRight[1], pBottomRight[2]);
osg::Vec3 v3(pTopRight[0], pTopRight[1], pTopRight[2]);
osg::Vec3 v4(pTopLeft[0], pTopLeft[1], pTopLeft[2]);
osg::Geometry* geom = new osg::Geometry;
geom->setDataVariance(osg::Object::DYNAMIC);
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = v1;
(*vertices)[1] = v2;
(*vertices)[2] = v3;
(*vertices)[3] = v4;
geom->setVertexArray(vertices);
osg::Vec2Array* texcoords = new osg::Vec2Array(4);
(*texcoords)[0].set(0.0f, 0.0f);
(*texcoords)[1].set(1, 0.0f);
(*texcoords)[2].set(1, 1);
(*texcoords)[3].set(0.0f, 1);
geom->setTexCoordArray(0, texcoords);
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(1);
(*normals)[0].set(0.0f, -1.0f, 0.0f);
geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f, 1.0f, 1.0f, 1.0f);
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
geom->setUseDisplayList(false);
osg::ref_ptr<osg::Image> img = new osg::Image;
img->setImage(image.GetWidth(), image.GetHeight(), 1,
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, image.GetPixelData(),
osg::Image::USE_NEW_DELETE);
//osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile("C:\\Users\\rupeshb\\Pictures\\error.bmp");
//osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile(filename);
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(img);
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat;
texmat->setScaleByTextureRectangleSize(true);
// setup state
osg::ref_ptr<osg::StateSet> state = geom->getOrCreateStateSet();
state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
state->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
pGeode->addDrawable(geom);
addChild(pGeode);
------------------
http://forum.openscenegraph.org/viewtopic.php?p=70254#70254
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
Evan Tsai
2017-02-18 21:57:20 UTC
Permalink
Thank you Robert.

Can you point me to more detailed documentation about the definition of these two parameters, packing and rowLength?

Thanks,
Evan
Post by Robert Osfield
HI Evan,
My best guess is that the packing of the data in each row is out, as
your Image::setData(..) call doesn't supply all the parameters
explicitly it will default to a packing of 1 byte.
For instance if the packing for your source data is 4 bytes, and all
you previous image data has a width with multiple of 4 then there
won't be any mismatch when using a 1 byte packing as it will select
the same width. However, if you use a width such as 3 then the source
data with a 4 byte packing would round up to 4 bytes width, but the
osg::Image::setImage() call you are using says just use 1 byte packing
so selects a width of 3. This will result in a each successive row
starting 1 byte off and leading to the "twist" you see.
Check the spec of your image reading code/file format to see what the
row packing is. Also have a look at the docs for
osg::Image::setImage(..), note the optional packing and rowLength
parameters.
Robert
Post by Evan Tsai
Thank you very much for helping. Below is how we make the call.
This has been working fine until very recently we received scan data from some CBCT scanners that we haven't encountered before. However those scans could be viewed correctly in all popular DICOM viewers in the market. As mentioned, I also took the pixel data and dumped it into a .bmp file, which looks correct. So the only possibility seems to be that we are missing some setting here......
I did try changing the texture coordinates around but that doesn't change the twisted nature of the display.
I also tried changing `packing' from 1 to 0 but that crashes the software.
Is there anything in particular that one needs to set for `rowLength'?
osg::Geode* pGeode = new osg::Geode;
osg::Vec3 v1(pBottomLeft[0], pBottomLeft[1], pBottomLeft[2]);
osg::Vec3 v2(pBottomRight[0], pBottomRight[1], pBottomRight[2]);
osg::Vec3 v3(pTopRight[0], pTopRight[1], pTopRight[2]);
osg::Vec3 v4(pTopLeft[0], pTopLeft[1], pTopLeft[2]);
osg::Geometry* geom = new osg::Geometry;
geom->setDataVariance(osg::Object::DYNAMIC);
osg::Vec3Array* vertices = new osg::Vec3Array(4);
(*vertices)[0] = v1;
(*vertices)[1] = v2;
(*vertices)[2] = v3;
(*vertices)[3] = v4;
geom->setVertexArray(vertices);
osg::Vec2Array* texcoords = new osg::Vec2Array(4);
(*texcoords)[0].set(0.0f, 0.0f);
(*texcoords)[1].set(1, 0.0f);
(*texcoords)[2].set(1, 1);
(*texcoords)[3].set(0.0f, 1);
geom->setTexCoordArray(0, texcoords);
osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array(1);
(*normals)[0].set(0.0f, -1.0f, 0.0f);
geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
osg::Vec4Array* colors = new osg::Vec4Array(1);
(*colors)[0].set(1.0f, 1.0f, 1.0f, 1.0f);
geom->setColorArray(colors, osg::Array::BIND_OVERALL);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
geom->setUseDisplayList(false);
osg::ref_ptr<osg::Image> img = new osg::Image;
img->setImage(image.GetWidth(), image.GetHeight(), 1,
GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, image.GetPixelData(),
osg::Image::USE_NEW_DELETE);
//osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile("C:\\Users\\rupeshb\\Pictures\\error.bmp");
//osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile(filename);
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(img);
texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat;
texmat->setScaleByTextureRectangleSize(true);
// setup state
osg::ref_ptr<osg::StateSet> state = geom->getOrCreateStateSet();
state->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
state->setTextureAttributeAndModes(0, texmat, osg::StateAttribute::ON | osg::StateAttribute::PROTECTED);
state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
pGeode->addDrawable(geom);
addChild(pGeode);
------------------
http://forum.openscenegraph.org/viewtopic.php?p=70254#70254
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
_______________________________________________
osg-users mailing list
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
------------------
Post generated by Mail2Forum
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=70274#70274
Robert Osfield
2017-02-19 08:19:43 UTC
Permalink
Post by Evan Tsai
Can you point me to more detailed documentation about the definition of these two parameters, packing and rowLength?
The parameters all related to OpenGL functions that define the packing
of the source image, packing and rowlength parameters are also
literally what they are.

Also If the doxgen docs aren't sufficient then go look at the
implementation i.e. src/osg/Image.cpp.

For you own tasks what will be important is what the source data is
packed as, the OSG can't help you with you, only you know what tool
you are using to read your image data, so it's down to you to do this
research.

Robert.

Loading...