[Insight-users] Image mask and SpatialObjects
Karthik Krishnan
karthik.krishnan at kitware.com
Tue Jul 13 07:56:17 EDT 2010
Thanks for pointing this out. I agree with all your observations. I'm not
sure what the correct solution is. My guess is that most of us have used the
mask spatial objects of the form (a) ImageMaskSpatialObject with masked
images (b) EllipsoidSpatialObject with an approximate ellipsoid defining the
brain (c) BoxSpatialObject, with a cuboid ROI on the target image.
For RTStruct data, we've converted them to ImageMaskSpatialObject and then
used them; because it simply did not seem to be a reasonable thing to
represent them as PolygonSpatialObject, given how slow the IsInside()
becomes. One has to do the line based voting against every polygon boundary
point; and do this for every pixel and transformed pixel; and at do this at
every iteration. The marginally improved precision of representing the ROI
as a mesh may not to be worth the time.
Thanks
--
karthik
On Tue, Jul 13, 2010 at 2:24 PM, Jäger Andreas
<A.Jaeger at dkfz-heidelberg.de>wrote:
> Hi,
>
>
>
> i had a problem concerning the usage of SpatialObjects (e.g.
> GroupSpatialObjects, ContourSpatialObjects, SpatialObjectTreeContainer,
> PolygonGroupSpatialObjects, PolygonSpatialObjects...) to mask a specific
> image for the registration.
>
> I think there are probably other people doing similar stuff, and there
> could be interest in discussing a few implementation decisions concerning
> SpatialObject child classes and the way the MeanSquaresImageToImageMetric is
> processing them.
>
> I use PolygonGroupSpatialObjects and PolygonSpatialObjects to create my own
> Volumes of Interest and Contours out of a set of points.
>
> I use these two SpatialObject types, because a)i import proprietary
> structure data, which is not pixel based (Thats the reason why I don't use
> ImageMaskSpatialObject for instance).
>
> b)the MeanSquaresImageToImageMetric is not working with any other
> combination of SpatialObject I tried so far (at least for the way i nest
> SpatialObjects).
>
>
>
> I store the Contours in PolygonSpatialObjects and store all contours of a
> VOI in PolygonGroupSpatialObjects.
>
> The Tree SpatialObject for all VOIs is also a PolygonGroupSpatialObject.
>
>
>
> As mentioned they are actually the only classes I can use, that’s why I
> wanted to discuss the implementation of a few other SpatialObject classes.
>
>
>
> For better understanding, here a part of my test program in pseudocode :
>
>
>
> create StructureLoader
>
> create RegistrationAlgorithm
>
> RegistrationAlgorithm->SetFixedImg()
>
> RegistrationAlgorithm->SetMovingImg()
>
> RegistrationAlgorithm->SetTargetMask(StrucureLoader->getStructure()) //
> returns the generated tree node object
>
> RegistrationAlgorithm->GetRegistration()
>
>
>
> The program delivers correct values(when trying to determine which image
> regios are inside/outside the mask) only,
>
> if I use the PolygonGroupSpatialObjects for nodes(voi and voi groups) and
> the PolygonSpatialObjects for leaves(contours).
>
>
>
> While trying to understand, why my implementation was not working as
> planned with other SpacialObject classes (e.g. GroupSpatialObjects,
> ContourSpatialObjects), I noticed several implementation decisions,
>
> which are responsible for the unexpected behavior.
>
> I have a few questions concerning the implementation of
> A)MeanSquaresImageToImageMetric::GetValueAndDerivative(...)/GroupSpatialObject::IsInside(...)
>
>
> B)PolygonSpatialObject::IsInside(...)/PolygonGroupSpatialObject::IsInside(...)
>
>
>
> and hope that someone is able to explain them to me.
>
>
>
> A)
>
>
>
> The MeanSquaresImageToImageMetric::GetValueAndDerivative() calls the
> IsInside() method without a parameter for the depth
>
>
>
> Line 178: if( this->m_FixedImageMask && !this->m_FixedImageMask->IsInside(
> inputPoint ) )
>
>
>
> which has the effect that for all SpatialObject classes(at least as far as
> i know) the default depth=0 is used.
>
>
>
> --> Was this implementation done with respect to the usage of
> SpatialObjects?
>
> I would assume if someone who is using SpatialObject would probably like
> to use the feature of creating tree like structures by nesting objects,
>
> but actually there are not many SpatialObjects which really check for
> existing childern, and rather use a depth = 0 as default?
>
> e.g. GroupSpatialObjects (i think this class is a good example, because
> you would expect a different behavior)
>
> GroupSpatialObject has no own implementation of IsInside()
>
> So the IsInside() Method checks as follows
>
>
>
> if( depth > 0 )
>
> {
>
> do something
>
> }
>
> else
>
> return false
>
>
>
> --> reasonable you always get false, when
> MeanSquaresImageToImageMetric::GetValueAndDerivative(...) checks the points
> of the image!
>
> Wouldn't it make more sense not to use the default IsInside
> implementation, because assuming a default depth=0 for GroupSpatialObjects
> seems to make no real sense.
>
> I can't really imagine, why someone should use a GroupSpatialObject with a
> depth of zero (for instance there could be a check of the childrenList if
> depth = 0 is passed).
>
>
>
> This is actually one reason why I use PolygonGroupSpatialObjects, because
> it was the only class I could find, which assumes it has children.
>
> I didn't check other metrics so far, so i don't know if they behave the
> same way.
>
>
>
> B)
>
>
>
> For testing purposes I wanted to use only one contour of a VOI, for faster
> processing
>
> pseudocode:
>
>
> RegistrationAlgorithm->setTargetMask(structureLoader.getContourSpatialObject()->GetFirstVOI()->GetFirstContour());
>
>
>
> I noticed, that if you use a PolygonSpecialObject without a
> PolygonGroupSpatialObjects, you get wrong return values for IsInside(),
>
> because there is no z-dimension check in the
> PolygonSpecialObject::IsInside(...) method.
>
> So if s.o. directly calls the PolygonSpecialObject::IsInside() method, he
> gets true for the points even if they are in an other plane than the
> polygon.
>
>
>
> this behavour forces you to use a PolygonGroupSpatialObject even if you
> would just have 1 PolygonSpecialObject inside.
>
> Can someone explain me, why PolygonSpecialObject was implemented that way?
> I think it is quite cofusing for someone, who works with theses classes the
> first time, because IsInside just doesn't behave as you would expect.
>
>
>
> compare itkPolygonSpatialObject.txx Line 403-485
>
>
>
> If I take a look at how MeanSquaresImageToImageMetric is using the
> IsInside() method, and the way method is implemented in the different
> classes, I somehow miss the "thread" in the way the parts are designed.
>
> But perhaps I just don't get the concept, I would appreciate it if someone
> could elucidate it for me ;). If someone thinks the way I build my
> Structures is a unfavorable solution, hints and tips are always welcome!
>
>
>
> Best regards
>
> Andreas
>
> _____________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://www.kitware.com/products/protraining.html
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100713/2a2947bb/attachment-0001.htm>
More information about the Insight-users
mailing list