[Insight-users] Image mask and SpatialObjects

Jäger Andreas A.Jaeger at Dkfz-Heidelberg.de
Tue Jul 13 04:54:24 EDT 2010


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/pipermail/insight-users/attachments/20100713/d02633a6/attachment-0001.htm>


More information about the Insight-users mailing list